From b956c0ede3f4b133b3d59df7c5427ad4c9cc22b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Bj=C3=B8rn=20J=C3=B8rgensen?= Date: Sat, 15 May 2010 20:07:07 +0200 Subject: [PATCH 1/4] Implemented the show/hide feature added the following options to make terminator able to behave like a drop-down terminal: hide from taskbar always on top hide on lose focus (experimental) sticky (Show on all workspaces) --- terminatorlib/config.py | 4 ++ terminatorlib/preferences.glade | 122 +++++++++++++++++++++++++++++++- terminatorlib/prefseditor.py | 32 +++++++++ terminatorlib/terminator.py | 2 +- terminatorlib/window.py | 66 ++++++++++++++--- 5 files changed, 215 insertions(+), 11 deletions(-) diff --git a/terminatorlib/config.py b/terminatorlib/config.py index e53ff766..8667bb27 100755 --- a/terminatorlib/config.py +++ b/terminatorlib/config.py @@ -85,6 +85,10 @@ DEFAULTS = { 'close_button_on_tab' : True, 'hide_tabbar' : False, 'scroll_tabbar' : False, + 'hide_from_taskbar' : False, + 'always_on_top' : False, + 'hide_on_lose_focus' : False, + 'sticky' : False, 'try_posix_regexp' : platform.system() != 'Linux', 'title_transmit_fg_color' : '#ffffff', 'title_transmit_bg_color' : '#c80003', diff --git a/terminatorlib/preferences.glade b/terminatorlib/preferences.glade index 78515b88..a95d70af 100644 --- a/terminatorlib/preferences.glade +++ b/terminatorlib/preferences.glade @@ -278,7 +278,7 @@ True - 6 + 10 2 6 @@ -469,6 +469,126 @@ 20 + + + True + Hide from taskbar + + + 6 + 7 + + + + + + + True + True + False + True + True + + + + 1 + 2 + 6 + 7 + + GTK_EXPAND + + + + + True + Always on top + + + 7 + 8 + + + + + + + True + Hide on lose focus + + + 8 + 9 + + + + + + + True + True + False + True + True + + + + 1 + 2 + 7 + 8 + + GTK_EXPAND + + + + + True + True + False + True + True + + + + 1 + 2 + 8 + 9 + + GTK_EXPAND + + + + + True + Show on all workspaces + + + 9 + 10 + + + + + + + True + True + False + True + True + + + + 1 + 2 + 9 + 10 + + GTK_EXPAND + + 0 diff --git a/terminatorlib/prefseditor.py b/terminatorlib/prefseditor.py index 0b6eb8f8..df2b6be2 100755 --- a/terminatorlib/prefseditor.py +++ b/terminatorlib/prefseditor.py @@ -207,6 +207,18 @@ class PrefsEditor: else: active = 0 widget.set_active(active) + #Hide from taskbar + widget = guiget('hidefromtaskbcheck') + widget.set_active(self.config['hide_from_taskbar']) + #Always on top + widget = guiget('alwaysontopcheck') + widget.set_active(self.config['always_on_top']) + #Hide on lose focus + widget = guiget('hideonlosefocuscheck') + widget.set_active(self.config['hide_on_lose_focus']) + #Show on all workspaces + widget = guiget('stickycheck') + widget.set_active(self.config['sticky']) ## Profile tab # Populate the profile list @@ -496,6 +508,26 @@ class PrefsEditor: self.config['borderless'] = not 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() + self.config.save() + + def on_alwaysontopcheck_toggled(self, widget): + """Always on top setting changed""" + self.config['always_on_top'] = widget.get_active() + self.config.save() + + def on_hideonlosefocuscheck_toggled(self, widget): + """Hide on lose focus setting changed""" + self.config['hide_on_lose_focus'] = widget.get_active() + self.config.save() + + def on_stickycheck_toggled(self, widget): + """Sticky setting changed""" + self.config['sticky'] = widget.get_active() + self.config.save() + def on_allow_bold_checkbutton_toggled(self, widget): """Allow bold setting changed""" self.config['allow_bold'] = widget.get_active() diff --git a/terminatorlib/terminator.py b/terminatorlib/terminator.py index e910026b..59158343 100755 --- a/terminatorlib/terminator.py +++ b/terminatorlib/terminator.py @@ -145,7 +145,7 @@ class Terminator(Borg): window = maker.make('Window') terminal = maker.make('Terminal') window.add(terminal) - window.show() + window.show(True) terminal.spawn_child() return(window, terminal) diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 2a6cfb34..8fda5acc 100755 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -32,8 +32,11 @@ class Window(Container, gtk.Window): title = None isfullscreen = None ismaximised = None + iswithdrawn = None hidebound = None hidefunc = None + position = None + ignore_startup_show = None zoom_data = None term_zoomed = gobject.property(type=bool, default=False) @@ -99,6 +102,10 @@ class Window(Container, gtk.Window): fullscreen = self.config['window_state'] == 'fullscreen' hidden = self.config['window_state'] == 'hidden' borderless = self.config['borderless'] + skiptaskbar = self.config['hide_from_taskbar'] + alwaysontop = self.config['always_on_top'] + hideonlosefocus = self.config['hide_on_lose_focus'] + sticky = self.config['sticky'] if options: if options.maximise: @@ -113,9 +120,13 @@ class Window(Container, gtk.Window): self.set_fullscreen(fullscreen) self.set_maximised(maximise) self.set_borderless(borderless) + self.set_always_on_top(alwaysontop) + self.set_hide_on_lose_focus(hideonlosefocus) self.set_real_transparency() + self.set_sticky(sticky) if self.hidebound: self.set_hidden(hidden) + self.set_skip_taskbar_hint(skiptaskbar) else: self.set_iconified(hidden) @@ -203,8 +214,18 @@ class Window(Container, gtk.Window): def on_hide_window(self, data=None): """Handle a request to hide/show the window""" - # FIXME: Implement or drop, or explain why its empty - pass + if self.iswithdrawn == True: + if self.position: + self.move(self.position[0], self.position[1]) + self.present() + else: + self.position = self.get_position() + self.hidefunc() + + def on_lose_focus(self, widget, event): + """Handle when window lose focus""" + self.position = self.get_position() + self.hidefunc() # pylint: disable-msg=W0613 def on_window_state_changed(self, window, event): @@ -213,8 +234,11 @@ class Window(Container, gtk.Window): gtk.gdk.WINDOW_STATE_FULLSCREEN) self.ismaximised = bool(event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED) - dbg('Window::on_window_state_changed: fullscreen=%s, maximised=%s' % - (self.isfullscreen, self.ismaximised)) + self.iswithdrawn = bool(event.new_window_state & + gtk.gdk.WINDOW_STATE_WITHDRAWN) + dbg('Window::on_window_state_changed: fullscreen=%s, maximised=%s,\ + withdrawn=%s' % + (self.isfullscreen, self.ismaximised, self.iswithdrawn)) return(False) @@ -238,13 +262,29 @@ class Window(Container, gtk.Window): def set_hidden(self, value): """Set the visibility of the window from the supplied value""" - # FIXME: Implement or drop this - pass + if value == True: + self.ignore_startup_show = True + else: + self.ignore_startup_show = False def set_iconified(self, value): - """Set the minimised state of the window from the value""" - # FIXME: Implement or drop this - pass + """Set the minimised state of the window from the supplied value""" + if value == True: + self.iconify() + + def set_always_on_top(self, value): + """Set the always on top window hint from the supplied value""" + self.set_keep_above(value) + + def set_sticky(self, value): + """Set the sticky hint from the supplied value""" + if value == True: + self.stick() + + def set_hide_on_lose_focus(self,value): + """Registers the callback for lost focus from the supplied value""" + if value == True: + self.connect('focus-out-event', self.on_lose_focus) def set_real_transparency(self, value=True): """Enable RGBA if supported on the current screen""" @@ -261,6 +301,14 @@ class Window(Container, gtk.Window): if colormap: self.set_colormap(colormap) + + def show(self, startup=False): + """Undo the startup show request if started in hidden mode""" + gtk.Window.show(self) + #Window must be shown, then hidden for the hotkeys to be registered + if (self.ignore_startup_show and startup == True): + self.hide() + def add(self, widget): """Add a widget to the window by way of gtk.Window.add()""" From 6a26db74655c322a8a549d9abc9e46d0271490e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20B=2E=20J=C3=B8rgensen?= Date: Tue, 13 Jul 2010 15:07:40 +0200 Subject: [PATCH 2/4] Fixed window not getting input focus when skip taskbar is set --- terminatorlib/window.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 6b8d7cca..15a59991 100755 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -259,7 +259,7 @@ class Window(Container, gtk.Window): if self.iswithdrawn == True: if self.position: self.move(self.position[0], self.position[1]) - self.present() + self.show() else: self.position = self.get_position() self.hidefunc() @@ -347,6 +347,9 @@ class Window(Container, gtk.Window): def show(self, startup=False): """Undo the startup show request if started in hidden mode""" gtk.Window.show(self) + #Present is necessary to grab focus when window is hidden from taskbar + self.present() + #Window must be shown, then hidden for the hotkeys to be registered if (self.ignore_startup_show and startup == True): self.hide() From b30197de06dc9408e03849ec6b0104d9cdc18b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20B=2E=20J=C3=B8rgensen?= Date: Wed, 14 Jul 2010 15:31:13 +0200 Subject: [PATCH 3/4] Fixed window flicker and/or reappearing when hide on lose focus is enabled --- terminatorlib/window.py | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 15a59991..1b52d53e 100755 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -4,6 +4,7 @@ """window.py - class for the main Terminator window""" import copy +import time import pygtk pygtk.require('2.0') import gobject @@ -31,9 +32,9 @@ class Window(Container, gtk.Window): title = None isfullscreen = None ismaximised = None - iswithdrawn = None hidebound = None hidefunc = None + losefocus_time = 0 position = None ignore_startup_show = None @@ -128,7 +129,6 @@ class Window(Container, gtk.Window): borderless = self.config['borderless'] skiptaskbar = self.config['hide_from_taskbar'] alwaysontop = self.config['always_on_top'] - hideonlosefocus = self.config['hide_on_lose_focus'] sticky = self.config['sticky'] if options: @@ -145,7 +145,6 @@ class Window(Container, gtk.Window): self.set_maximised(maximise) self.set_borderless(borderless) self.set_always_on_top(alwaysontop) - self.set_hide_on_lose_focus(hideonlosefocus) self.set_real_transparency() self.set_sticky(sticky) if self.hidebound: @@ -200,6 +199,11 @@ class Window(Container, gtk.Window): for terminal in self.get_visible_terminals(): terminal.on_window_focus_out() + self.losefocus_time = time.time() + if self.config['hide_on_lose_focus'] and self.get_property('visible'): + self.position = self.get_position() + self.hidefunc() + def on_focus_in(self, window, event): """Focus has entered the window""" self.set_urgency_hint(False) @@ -256,7 +260,12 @@ class Window(Container, gtk.Window): def on_hide_window(self, data=None): """Handle a request to hide/show the window""" - if self.iswithdrawn == True: + + if not self.get_property('visible'): + #Don't show if window has just been hidden because of + #e.g. lost focus + if time.time() - self.losefocus_time < 0.1: + return if self.position: self.move(self.position[0], self.position[1]) self.show() @@ -264,11 +273,6 @@ class Window(Container, gtk.Window): self.position = self.get_position() self.hidefunc() - def on_lose_focus(self, widget, event): - """Handle when window lose focus""" - self.position = self.get_position() - self.hidefunc() - # pylint: disable-msg=W0613 def on_window_state_changed(self, window, event): """Handle the state of the window changing""" @@ -276,11 +280,8 @@ class Window(Container, gtk.Window): gtk.gdk.WINDOW_STATE_FULLSCREEN) self.ismaximised = bool(event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED) - self.iswithdrawn = bool(event.new_window_state & - gtk.gdk.WINDOW_STATE_WITHDRAWN) - dbg('Window::on_window_state_changed: fullscreen=%s, maximised=%s,\ - withdrawn=%s' % - (self.isfullscreen, self.ismaximised, self.iswithdrawn)) + dbg('Window::on_window_state_changed: fullscreen=%s, maximised=%s' \ + % (self.isfullscreen, self.ismaximised)) return(False) @@ -323,11 +324,6 @@ class Window(Container, gtk.Window): if value == True: self.stick() - def set_hide_on_lose_focus(self,value): - """Registers the callback for lost focus from the supplied value""" - if value == True: - self.connect('focus-out-event', self.on_lose_focus) - def set_real_transparency(self, value=True): """Enable RGBA if supported on the current screen""" if self.is_composited() == False: From 89230457a1f1b865ff8e50511d4ae571ae8176df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20B=2E=20J=C3=B8rgensen?= Date: Thu, 15 Jul 2010 16:42:31 +0200 Subject: [PATCH 4/4] only prevent faulty reappearing when hide_on_lose_focus is enabled --- terminatorlib/window.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 1b52d53e..e1eac66a 100755 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -263,8 +263,9 @@ class Window(Container, gtk.Window): if not self.get_property('visible'): #Don't show if window has just been hidden because of - #e.g. lost focus - if time.time() - self.losefocus_time < 0.1: + #lost focus + if (time.time() - self.losefocus_time < 0.1) and \ + self.config['hide_on_lose_focus']: return if self.position: self.move(self.position[0], self.position[1])