diff --git a/terminatorlib/config.py b/terminatorlib/config.py index 813c56b3..2a6b254d 100755 --- a/terminatorlib/config.py +++ b/terminatorlib/config.py @@ -94,6 +94,7 @@ DEFAULTS = { 'geometry_hinting' : False, 'window_state' : 'normal', 'borderless' : False, + 'extra_styling' : True, 'tab_position' : 'top', 'broadcast_default' : 'group', 'close_button_on_tab' : True, diff --git a/terminatorlib/preferences.glade b/terminatorlib/preferences.glade index 6a1533ad..ce27f935 100644 --- a/terminatorlib/preferences.glade +++ b/terminatorlib/preferences.glade @@ -849,6 +849,36 @@ False 6 12 + + + Window borders + False + True + True + False + 0.5 + True + True + + + + 0 + 3 + 3 + + + + + True + False + Unfocused terminal font brightness: + 0 + + + 0 + 2 + + True @@ -858,23 +888,7 @@ 0 - 0 - - - - - True - False - -1 - right - 5 - 5 - 1 - 1 - - - 1 - 0 + 1 @@ -893,34 +907,6 @@ 2 - 0 - - - - - True - False - Unfocused terminal font brightness: - 0 - - - 0 - 1 - - - - - True - False - 100% - right - 5 - 5 - 1 - 1 - - - 1 1 @@ -940,24 +926,56 @@ 2 + 2 + + + + + True + False + -1 + right + 5 + 5 + 1 + 1 + + + 1 1 - - Window borders + + True + False + 100% + right + 5 + 5 + 1 + 1 + + + 1 + 2 + + + + + Extra Styling (Theme dependant) False True True False - 0.5 + 0 True True - + 0 - 2 + 0 3 diff --git a/terminatorlib/prefseditor.py b/terminatorlib/prefseditor.py index 736b17e7..85b5c60e 100755 --- a/terminatorlib/prefseditor.py +++ b/terminatorlib/prefseditor.py @@ -254,6 +254,9 @@ class PrefsEditor: # Window borders widget = guiget('winbordercheck') widget.set_active(not self.config['borderless']) + # Extra styling + widget = guiget('extrastylingcheck') + widget.set_active(self.config['extra_styling']) # Tab bar position option = self.config['tab_position'] widget = guiget('tabposcombo') @@ -692,6 +695,11 @@ class PrefsEditor: self.config['borderless'] = not widget.get_active() self.config.save() + def on_extrastylingcheck_toggled(self, widget): + """Extra styling setting changed""" + self.config['extra_styling'] = widget.get_active() + self.config.save() + def on_hidefromtaskbcheck_toggled(self, widget): """Hide from taskbar setting changed""" self.config['hide_from_taskbar'] = widget.get_active() diff --git a/terminatorlib/searchbar.py b/terminatorlib/searchbar.py index c4e7625f..a142a633 100755 --- a/terminatorlib/searchbar.py +++ b/terminatorlib/searchbar.py @@ -39,6 +39,8 @@ class Searchbar(Gtk.HBox): self.config = Config() + self.get_style_context().add_class("terminator-terminal-searchbar") + # Search text self.entry = Gtk.Entry() self.entry.set_activates_default(True) diff --git a/terminatorlib/terminal.py b/terminatorlib/terminal.py index 0ee4851d..fa8d7a1b 100755 --- a/terminatorlib/terminal.py +++ b/terminatorlib/terminal.py @@ -734,6 +734,16 @@ class Terminal(Gtk.VBox): else: self.vte.set_colors(self.fgcolor_inactive, self.bgcolor, self.palette_inactive) + profiles = self.config.base.profiles + terminal_box_style_context = self.terminalbox.get_style_context() + for profile in profiles.keys(): + munged_profile = "terminator-profile-%s" % ( + "".join([c if c.isalnum() else "-" for c in profile])) + if terminal_box_style_context.has_class(munged_profile): + terminal_box_style_context.remove_class(munged_profile) + munged_profile = "".join([c if c.isalnum() else "-" for c in self.get_profile()]) + css_class_name = "terminator-profile-%s" % (munged_profile) + terminal_box_style_context.add_class(css_class_name) self.set_cursor_color() self.vte.set_cursor_shape(getattr(Vte.CursorShape, self.config['cursor_shape'].upper())); diff --git a/terminatorlib/terminator.py b/terminatorlib/terminator.py index ecab175b..977d8603 100755 --- a/terminatorlib/terminator.py +++ b/terminatorlib/terminator.py @@ -5,8 +5,11 @@ import copy import os -from gi.repository import Gtk, Gdk +import gi +gi.require_version('Vte', '2.91') +from gi.repository import Gtk, Gdk, Vte +import borg from borg import Borg from config import Config from keybindings import Keybindings @@ -39,7 +42,7 @@ class Terminator(Borg): groups = None config = None keybindings = None - style_provider = None + style_providers = None last_focused_term = None origcwd = None @@ -57,6 +60,9 @@ class Terminator(Borg): groupsend = None groupsend_type = {'all':0, 'group':1, 'off':2} + cur_gtk_theme_name = None + gtk_settings = None + def __init__(self): """Class initialiser""" @@ -81,12 +87,21 @@ class Terminator(Borg): if not self.keybindings: self.keybindings = Keybindings() self.keybindings.configure(self.config['keybindings']) + if not self.style_providers: + self.style_providers = [] if not self.doing_layout: self.doing_layout = False if not self.pid_cwd: self.pid_cwd = get_pid_cwd() if self.gnome_client is None: self.attempt_gnome_client() + self.connect_signals() + + def connect_signals(self): + """Connect all the gtk signals""" + self.gtk_settings=Gtk.Settings().get_default() + self.gtk_settings.connect('notify::gtk-theme-name', self.on_gtk_theme_name_notify) + self.cur_gtk_theme_name = self.gtk_settings.get_property('gtk-theme-name') def set_origcwd(self, cwd): """Store the original cwd our process inherits""" @@ -365,34 +380,125 @@ class Terminator(Borg): if window.uuid == self.last_active_window: window.show() + def on_gtk_theme_name_notify(self, settings, prop): + """Reconfigure if the gtk theme name changes""" + new_gtk_theme_name = settings.get_property(prop.name) + if new_gtk_theme_name != self.cur_gtk_theme_name: + self.cur_gtk_theme_name = new_gtk_theme_name + self.reconfigure() + def reconfigure(self): """Update configuration for the whole application""" - if self.style_provider is not None: - Gtk.StyleContext.remove_provider_for_screen( - Gdk.Screen.get_default(), - self.style_provider) - self.style_provider = None + if self.style_providers != []: + for style_provider in self.style_providers: + Gtk.StyleContext.remove_provider_for_screen( + Gdk.Screen.get_default(), + style_provider) + self.style_providers = [] + # Force the window background to be transparent for newer versions of + # GTK3. We then have to fix all the widget backgrounds because the + # widgets theming may not render it's own background. css = """ - GtkPaned { - margin: 0 0 0 0; - padding: 0 0 0 0; - } + .terminator-terminal-window { + background-color: alpha(@theme_bg_color,0); } + + .terminator-terminal-window .notebook.header { + background-color: @theme_bg_color; } + + .terminator-terminal-window .pane-separator { + background-color: @theme_bg_color; } + + .terminator-terminal-window .terminator-terminal-searchbar { + background-color: @theme_bg_color; } """ + # Fix several themes that put a borders, corners, or backgrounds around + # viewports, making the titlebar look bad. + css += """ + .terminator-terminal-window GtkViewport { + border-width: 0px; + border-radius: 0px; + background-color: transparent; } + """ + + # Add per profile snippets for setting the background of the HBox + template = """ + .terminator-profile-%s { + background-color: alpha(%s, %s); } + """ + profiles = self.config.base.profiles + for profile in profiles.keys(): + if profiles[profile]['use_theme_colors']: + # Create a dummy window/vte and realise it so it has correct + # values to read from + tmp_win = Gtk.Window() + tmp_vte = Vte.Terminal() + tmp_win.add(tmp_vte) + tmp_win.realize() + bgcolor = tmp_vte.get_style_context().get_background_color(Gtk.StateType.NORMAL) + bgcolor = "#{0:02x}{1:02x}{2:02x}".format(int(bgcolor.red * 255), + int(bgcolor.green * 255), + int(bgcolor.blue * 255)) + tmp_win.remove(tmp_vte) + del(tmp_vte) + del(tmp_win) + else: + bgcolor = Gdk.RGBA() + bgcolor = profiles[profile]['background_color'] + if profiles[profile]['background_type'] == 'transparent': + bgalpha = profiles[profile]['background_darkness'] + else: + bgalpha = "1" + + munged_profile = "".join([c if c.isalnum() else "-" for c in profile]) + css += template % (munged_profile, bgcolor, bgalpha) + + style_provider = Gtk.CssProvider() + style_provider.load_from_data(css) + self.style_providers.append(style_provider) + + # Attempt to load some theme specific stylistic tweaks for appearances + usr_theme_dir = os.path.expanduser('~/.local/share/themes') + (head, _tail) = os.path.split(borg.__file__) + app_theme_dir = os.path.join(head, 'themes') + + theme_name = self.gtk_settings.get_property('gtk-theme-name') + + theme_part_list = ['terminator.css'] + if self.config['extra_styling']: # checkbox_style - needs adding to prefs + theme_part_list.append('terminator_styling.css') + for theme_part_file in theme_part_list: + for theme_dir in [usr_theme_dir, app_theme_dir]: + path_to_theme_specific_css = os.path.join(theme_dir, + theme_name, + 'gtk-3.0/apps', + theme_part_file) + if os.path.isfile(path_to_theme_specific_css): + style_provider = Gtk.CssProvider() + style_provider.load_from_path(path_to_theme_specific_css) + self.style_providers.append(style_provider) + break + + # Size the GtkPaned splitter handle size. + css = "" if self.config['handle_size'] in xrange(0, 21): css += """ - GtkPaned { - -GtkPaned-handle-size: %s - } + .terminator-terminal-window GtkPaned { + -GtkPaned-handle-size: %s; } """ % self.config['handle_size'] - self.style_provider = Gtk.CssProvider() - self.style_provider.load_from_data(css) - Gtk.StyleContext.add_provider_for_screen( - Gdk.Screen.get_default(), - self.style_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) + style_provider = Gtk.CssProvider() + style_provider.load_from_data(css) + self.style_providers.append(style_provider) + + # Apply the providers, incrementing priority so they don't cancel out + # each other + for idx in xrange(0, len(self.style_providers)): + Gtk.StyleContext.add_provider_for_screen( + Gdk.Screen.get_default(), + self.style_providers[idx], + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION+idx) # Cause all the terminals to reconfigure for terminal in self.terminals: diff --git a/terminatorlib/themes/Adwaita/gtk-3.0/apps/terminator.css b/terminatorlib/themes/Adwaita/gtk-3.0/apps/terminator.css new file mode 100644 index 00000000..faaf58ab --- /dev/null +++ b/terminatorlib/themes/Adwaita/gtk-3.0/apps/terminator.css @@ -0,0 +1,5 @@ +/* Fixes oversized hover area preventing selecting characters. */ +.terminator-terminal-window GtkPaned { + margin: 0 0 0 0; + padding: 0 0 0 0; } + diff --git a/terminatorlib/themes/Ambiance/gtk-3.0/apps/terminator.css b/terminatorlib/themes/Ambiance/gtk-3.0/apps/terminator.css new file mode 100644 index 00000000..8d9de724 --- /dev/null +++ b/terminatorlib/themes/Ambiance/gtk-3.0/apps/terminator.css @@ -0,0 +1,9 @@ +.terminator-terminal-window .scrollbar.dragging:not(.slider), +.terminator-terminal-window .scrollbar:hover:not(.slider), +.terminator-terminal-window .scrollbar:not(.slider) { + background-color: alpha(@dark_bg_color,0); +} + +.terminator-terminal-window .scrollbar:hover:not(.slider) { + background-color: alpha(@scrollbar_track_color, 0.4); +} diff --git a/terminatorlib/themes/Ambiance/gtk-3.0/apps/terminator_styling.css b/terminatorlib/themes/Ambiance/gtk-3.0/apps/terminator_styling.css new file mode 100644 index 00000000..4d46e124 --- /dev/null +++ b/terminatorlib/themes/Ambiance/gtk-3.0/apps/terminator_styling.css @@ -0,0 +1,89 @@ +/* +Some basic playing copying out the GNOME-Terminal style tab headers. + +Might want to have a seperate option for "shrinking" the tabs, by +nuking the padding/borders in the tabs. +*/ + +.terminator-terminal-window .notebook.header { + border-width: 0; /* set below depending on position of tab bar */ + border-color: shade (@bg_color, 0.82); + border-style: solid; + border-radius: 0px 0px 0px 0px; + background-color: @dark_bg_color; +} + +/* Draw a border between tabs and content ... */ +.terminator-terminal-window .notebook.header.top { border-bottom-width: 1px; } +.terminator-terminal-window .notebook.header.right { border-left-width: 1px; } +.terminator-terminal-window .notebook.header.left { border-right-width: 1px; } +.terminator-terminal-window .notebook.header.bottom { border-top-width: 1px; } + +/* ... unless the content is in a frame (thus having a border itself */ +.terminator-terminal-window .notebook.header.frame.top { border: none; } +.terminator-terminal-window .notebook.header.frame.right { border: none; } +.terminator-terminal-window .notebook.header.frame.right { border: none; } +.terminator-terminal-window .notebook.header.frame.bottom { border: none; } + + +.terminator-terminal-window .notebook tab { + background-color: shade(@bg_color, 0.7); + border-image: none; + border-style: solid; + border-color: @dark_bg_color; +} + +/* give active tab a background, as it might be dragged across of others when reordering */ +.terminator-terminal-window .notebook tab:active { + background-color: @bg_color; +} + +.terminator-terminal-window .notebook tab.top:active { padding-bottom: 3px; } +.terminator-terminal-window .notebook tab.bottom:active { padding-top: 3px; } +.terminator-terminal-window .notebook tab.left:active { padding-right: 5px; } +.terminator-terminal-window .notebook tab.right:active { padding-left: 5px; } + +.terminator-terminal-window .notebook tab.top { + padding: 4px 6px 2px 6px; + border-width: 1px 1px 0px 1px; + border-radius: 8px 8px 0px 0px; +} + +.terminator-terminal-window .notebook tab.bottom { + padding: 2px 6px 4px 6px; + border-width: 0px 1px 1px 1px; + border-radius: 0px 0px 8px 8px; +} + +.terminator-terminal-window .notebook tab.left { + padding: 2px 4px 2px 6px; + border-width: 1px 0px 1px 1px; + border-radius: 8px 0px 0px 8px; +} + +.terminator-terminal-window .notebook tab.right { + padding: 2px 6px 2px 4px; + border-width: 1px 1px 1px 0px; + border-radius: 0px 8px 8px 0px; +} + +.terminator-terminal-window .notebook tab .button { + background-color: transparent; + padding: 1px; +} + +/* Draw a focus ring around labels in tabs */ +.terminator-terminal-window .notebook tab GtkLabel { + border: 1px solid transparent; + border-radius: 5px; +} + +.terminator-terminal-window .notebook:focus tab GtkLabel.active-page { + border-color: @focus_color; + background-color: @focus_bg_color; +} + +.terminator-terminal-window .notebook GtkDrawingArea { + background-color: shade (@bg_color, 1.02); +} + diff --git a/terminatorlib/themes/Breeze/gtk-3.0/apps/terminator.css b/terminatorlib/themes/Breeze/gtk-3.0/apps/terminator.css new file mode 100644 index 00000000..a5895563 --- /dev/null +++ b/terminatorlib/themes/Breeze/gtk-3.0/apps/terminator.css @@ -0,0 +1,12 @@ +/* Fixes oversized hover area preventing selecting characters. */ +.terminator-terminal-window GtkPaned { + margin: 0 0 0 0; + padding: 0 0 0 0; } + +/* First attempt at fixing the scrollbars */ +.terminator-terminal-window .scrollbar .trough, +.terminator-terminal-window .scrollbar .button { + background-color: @theme_bg_color; + border-radius: 0px +} + diff --git a/terminatorlib/themes/HighContrast/gtk-3.0/apps/terminator.css b/terminatorlib/themes/HighContrast/gtk-3.0/apps/terminator.css new file mode 100644 index 00000000..0736b8ca --- /dev/null +++ b/terminatorlib/themes/HighContrast/gtk-3.0/apps/terminator.css @@ -0,0 +1,6 @@ +/* First attempt to fix scrollbars being transparent */ + +.terminator-terminal-window .scrollbar .trough { + background-color: @theme_bg_color; +} + diff --git a/terminatorlib/themes/Radiance/gtk-3.0/apps/terminator.css b/terminatorlib/themes/Radiance/gtk-3.0/apps/terminator.css new file mode 100644 index 00000000..8d9de724 --- /dev/null +++ b/terminatorlib/themes/Radiance/gtk-3.0/apps/terminator.css @@ -0,0 +1,9 @@ +.terminator-terminal-window .scrollbar.dragging:not(.slider), +.terminator-terminal-window .scrollbar:hover:not(.slider), +.terminator-terminal-window .scrollbar:not(.slider) { + background-color: alpha(@dark_bg_color,0); +} + +.terminator-terminal-window .scrollbar:hover:not(.slider) { + background-color: alpha(@scrollbar_track_color, 0.4); +} diff --git a/terminatorlib/themes/Radiance/gtk-3.0/apps/terminator_styling.css b/terminatorlib/themes/Radiance/gtk-3.0/apps/terminator_styling.css new file mode 100644 index 00000000..4d46e124 --- /dev/null +++ b/terminatorlib/themes/Radiance/gtk-3.0/apps/terminator_styling.css @@ -0,0 +1,89 @@ +/* +Some basic playing copying out the GNOME-Terminal style tab headers. + +Might want to have a seperate option for "shrinking" the tabs, by +nuking the padding/borders in the tabs. +*/ + +.terminator-terminal-window .notebook.header { + border-width: 0; /* set below depending on position of tab bar */ + border-color: shade (@bg_color, 0.82); + border-style: solid; + border-radius: 0px 0px 0px 0px; + background-color: @dark_bg_color; +} + +/* Draw a border between tabs and content ... */ +.terminator-terminal-window .notebook.header.top { border-bottom-width: 1px; } +.terminator-terminal-window .notebook.header.right { border-left-width: 1px; } +.terminator-terminal-window .notebook.header.left { border-right-width: 1px; } +.terminator-terminal-window .notebook.header.bottom { border-top-width: 1px; } + +/* ... unless the content is in a frame (thus having a border itself */ +.terminator-terminal-window .notebook.header.frame.top { border: none; } +.terminator-terminal-window .notebook.header.frame.right { border: none; } +.terminator-terminal-window .notebook.header.frame.right { border: none; } +.terminator-terminal-window .notebook.header.frame.bottom { border: none; } + + +.terminator-terminal-window .notebook tab { + background-color: shade(@bg_color, 0.7); + border-image: none; + border-style: solid; + border-color: @dark_bg_color; +} + +/* give active tab a background, as it might be dragged across of others when reordering */ +.terminator-terminal-window .notebook tab:active { + background-color: @bg_color; +} + +.terminator-terminal-window .notebook tab.top:active { padding-bottom: 3px; } +.terminator-terminal-window .notebook tab.bottom:active { padding-top: 3px; } +.terminator-terminal-window .notebook tab.left:active { padding-right: 5px; } +.terminator-terminal-window .notebook tab.right:active { padding-left: 5px; } + +.terminator-terminal-window .notebook tab.top { + padding: 4px 6px 2px 6px; + border-width: 1px 1px 0px 1px; + border-radius: 8px 8px 0px 0px; +} + +.terminator-terminal-window .notebook tab.bottom { + padding: 2px 6px 4px 6px; + border-width: 0px 1px 1px 1px; + border-radius: 0px 0px 8px 8px; +} + +.terminator-terminal-window .notebook tab.left { + padding: 2px 4px 2px 6px; + border-width: 1px 0px 1px 1px; + border-radius: 8px 0px 0px 8px; +} + +.terminator-terminal-window .notebook tab.right { + padding: 2px 6px 2px 4px; + border-width: 1px 1px 1px 0px; + border-radius: 0px 8px 8px 0px; +} + +.terminator-terminal-window .notebook tab .button { + background-color: transparent; + padding: 1px; +} + +/* Draw a focus ring around labels in tabs */ +.terminator-terminal-window .notebook tab GtkLabel { + border: 1px solid transparent; + border-radius: 5px; +} + +.terminator-terminal-window .notebook:focus tab GtkLabel.active-page { + border-color: @focus_color; + background-color: @focus_bg_color; +} + +.terminator-terminal-window .notebook GtkDrawingArea { + background-color: shade (@bg_color, 1.02); +} + diff --git a/terminatorlib/themes/Raleigh/gtk-3.0/apps/terminator.css b/terminatorlib/themes/Raleigh/gtk-3.0/apps/terminator.css new file mode 100644 index 00000000..880a541c --- /dev/null +++ b/terminatorlib/themes/Raleigh/gtk-3.0/apps/terminator.css @@ -0,0 +1,16 @@ +/* Raleigh is so old, it doesn't use the correct public colours */ +.terminator-terminal-window { + background-color: alpha(@bg_color,0); } + +.terminator-terminal-window .notebook { + background-color: @bg_color; } + +.terminator-terminal-window .notebook.header { + background-color: @bg_color; } + +.terminator-terminal-window .pane-separator { + background-color: @bg_color; } + +.terminator-terminal-window .terminator-terminal-searchbar { + background-color: @bg_color; } + diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 038972bb..13505fa6 100755 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -64,6 +64,8 @@ class Window(Container, Gtk.Window): GObject.type_register(Window) self.register_signals(Window) + self.get_style_context().add_class("terminator-terminal-window") + # self.set_property('allow-shrink', True) # FIXME FOR GTK3, or do we need this actually? icon_to_apply=''