Re-adding guake like functionality comit after bungled merge
This commit is contained in:
parent
6d225c7aee
commit
9248fc9340
@ -90,6 +90,30 @@ Specify the preferred size and position of Terminator\(cqs window;
|
|||||||
see \fBX\fP(7).
|
see \fBX\fP(7).
|
||||||
.RE
|
.RE
|
||||||
.sp
|
.sp
|
||||||
|
\fB\-\-guake\-key\fP=\fIGUAKE_KEY\fP
|
||||||
|
.RS 4
|
||||||
|
A Guake like terminal mode where terminal can be toggled by a key.
|
||||||
|
Usage Example: terminator \-\-guake\-key="F8" \-\-guake\-side left \-\-guake\-width 700 \-\-guake\-height 800
|
||||||
|
.RE
|
||||||
|
.sp
|
||||||
|
\fB\-\-guake\-side\fP=\fIGUAKE_SIDE\fP
|
||||||
|
.RS 4
|
||||||
|
Set the preferred screen edge position of a terminal in Guake like mode.
|
||||||
|
Options: top, bottom, left, right
|
||||||
|
Default: top
|
||||||
|
.RE
|
||||||
|
.sp
|
||||||
|
\fB\-\-guake\-width\fP=\fIGUAKE_WIDTH\fP
|
||||||
|
.RS 4
|
||||||
|
Set the preferred width when using Guake like mode.
|
||||||
|
Default: 800
|
||||||
|
.RE
|
||||||
|
.sp
|
||||||
|
\fB\-\-guake\-height\fP=\fIGUAKE_HEIGHT\fP
|
||||||
|
.RS 4
|
||||||
|
Set the preferred height when using Guake like mode.
|
||||||
|
Default: 600
|
||||||
|
.sp
|
||||||
\fB\-e\fP \fICOMMAND\fP, \fB\-\-command\fP=\fICOMMAND\fP
|
\fB\-e\fP \fICOMMAND\fP, \fB\-\-command\fP=\fICOMMAND\fP
|
||||||
.RS 4
|
.RS 4
|
||||||
Run the specified command instead of the default shell or profile
|
Run the specified command instead of the default shell or profile
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"""Terminator.optionparse - Parse commandline options"""
|
"""Terminator.optionparse - Parse commandline options"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
from argparse import RawTextHelpFormatter
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ def parse_options():
|
|||||||
"""Parse the command line options"""
|
"""Parse the command line options"""
|
||||||
is_x_terminal_emulator = os.path.basename(sys.argv[0]) == 'x-terminal-emulator'
|
is_x_terminal_emulator = os.path.basename(sys.argv[0]) == 'x-terminal-emulator'
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter)
|
||||||
|
|
||||||
parser.add_argument('-R', '--reload', action='store_true', dest='reload',
|
parser.add_argument('-R', '--reload', action='store_true', dest='reload',
|
||||||
help=_('Reload terminator configuration'))
|
help=_('Reload terminator configuration'))
|
||||||
@ -59,6 +60,16 @@ def parse_options():
|
|||||||
parser.add_argument('--geometry', dest='geometry', type=str,
|
parser.add_argument('--geometry', dest='geometry', type=str,
|
||||||
help=_('Set the preferred size and position of the window'
|
help=_('Set the preferred size and position of the window'
|
||||||
'(see X man page)'))
|
'(see X man page)'))
|
||||||
|
parser.add_argument('--guake-key', dest='guake_key', type=str,
|
||||||
|
help=_('A Guake like terminal mode where terminal can be toggled by a key.\nUsage Example: terminator --guake-key="F8" --guake-side left --guake-width 700 --guake-height 800'))
|
||||||
|
parser.add_argument('--guake-side', dest='guake_side', default="top", type=str,
|
||||||
|
help=_('Set the preferred screen edge position of a terminal in Guake like mode.\nOptions: top, bottom, left, right\nDefault: top'))
|
||||||
|
parser.add_argument('--guake-width', dest='guake_width', default="800", type=str,
|
||||||
|
help=_('Set the preferred width when using Guake like mode. Default: 800'
|
||||||
|
'(see X man page)'))
|
||||||
|
parser.add_argument('--guake-height', dest='guake_height', default="600", type=str,
|
||||||
|
help=_('Set the preferred height when using Guake like mode. Default: 600'
|
||||||
|
'(see X man page)'))
|
||||||
if not is_x_terminal_emulator:
|
if not is_x_terminal_emulator:
|
||||||
parser.add_argument('-e', '--command', dest='command',
|
parser.add_argument('-e', '--command', dest='command',
|
||||||
help=_('Specify a command to execute inside the terminal'))
|
help=_('Specify a command to execute inside the terminal'))
|
||||||
|
@ -77,13 +77,16 @@ class Window(Container, Gtk.Window):
|
|||||||
# self.set_property('allow-shrink', True) # FIXME FOR GTK3, or do we need this actually?
|
# self.set_property('allow-shrink', True) # FIXME FOR GTK3, or do we need this actually?
|
||||||
icon_to_apply=''
|
icon_to_apply=''
|
||||||
|
|
||||||
self.register_callbacks()
|
|
||||||
self.apply_config()
|
self.apply_config()
|
||||||
|
|
||||||
self.title = WindowTitle(self)
|
self.title = WindowTitle(self)
|
||||||
self.title.update()
|
self.title.update()
|
||||||
|
|
||||||
self.preventHide = False
|
self.preventHide = False
|
||||||
|
|
||||||
|
self.display = Gdk.Display().get_default()
|
||||||
|
self.mouse = self.display.get_default_seat().get_pointer()
|
||||||
|
self.guake_key = None
|
||||||
|
|
||||||
options = self.config.options_get()
|
options = self.config.options_get()
|
||||||
if options:
|
if options:
|
||||||
@ -92,15 +95,44 @@ class Window(Container, Gtk.Window):
|
|||||||
|
|
||||||
if options.role:
|
if options.role:
|
||||||
self.set_role(options.role)
|
self.set_role(options.role)
|
||||||
|
|
||||||
if options.forcedicon is not None:
|
if options.forcedicon is not None:
|
||||||
icon_to_apply = options.forcedicon
|
icon_to_apply = options.forcedicon
|
||||||
|
|
||||||
if options.geometry:
|
if options.geometry:
|
||||||
if not self.parse_geometry(options.geometry):
|
if not self.parse_geometry(options.geometry):
|
||||||
err('Window::__init__: Unable to parse geometry: %s' %
|
err('Window::__init__: Unable to parse geometry: %s' %
|
||||||
options.geometry)
|
options.geometry)
|
||||||
|
|
||||||
|
if options.guake_key:
|
||||||
|
self.guake_key = options.guake_key
|
||||||
|
|
||||||
|
if options.guake_side and options.guake_width and options.guake_height:
|
||||||
|
proceed_undecorated = True
|
||||||
|
|
||||||
|
if options.guake_side in ["top", "bottom", "left", "right"]:
|
||||||
|
self.guake_side = options.guake_side
|
||||||
|
else:
|
||||||
|
proceed_undecorated = False
|
||||||
|
err('Window::__init__: Unable to parse guake_side: %s' %
|
||||||
|
options.guake_side)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.guake_width = int(options.guake_width)
|
||||||
|
self.guake_height = int(options.guake_height)
|
||||||
|
except Exception as e:
|
||||||
|
proceed_undecorated = False
|
||||||
|
err('Window::__init__: Unable to parse guake_width: %s and/or guake_height: %s' %
|
||||||
|
options.guake_width, options.guake_height)
|
||||||
|
|
||||||
|
if proceed_undecorated:
|
||||||
|
self.set_decorated(False)
|
||||||
|
self.set_default_size(self.guake_width, self.guake_height)
|
||||||
|
else:
|
||||||
|
self.guake_key = None
|
||||||
|
|
||||||
|
self.register_callbacks()
|
||||||
|
|
||||||
self.apply_icon(icon_to_apply)
|
self.apply_icon(icon_to_apply)
|
||||||
self.pending_set_rough_geometry_hint = False
|
self.pending_set_rough_geometry_hint = False
|
||||||
self.hidefunc = self.hide
|
self.hidefunc = self.hide
|
||||||
@ -119,6 +151,35 @@ class Window(Container, Gtk.Window):
|
|||||||
else:
|
else:
|
||||||
raise AttributeError('unknown property %s' % prop.name)
|
raise AttributeError('unknown property %s' % prop.name)
|
||||||
|
|
||||||
|
# NOTE: Gdk.VisibilityState.UNOBSCURED presumably isn't reliable due to transparency in moddern wms.
|
||||||
|
# Seems to work okay for our needs but should be kept in mind for future changes....
|
||||||
|
def _bind_window_to_position(self, widget, eve):
|
||||||
|
if eve.state == Gdk.VisibilityState.UNOBSCURED:
|
||||||
|
screen, mouse_x, mouse_y = self.mouse.get_position()
|
||||||
|
monitor = self.display.get_monitor_at_point(mouse_x, mouse_y)
|
||||||
|
window_w, window_h = self.guake_width, self.guake_height
|
||||||
|
geom_rect = monitor.get_geometry()
|
||||||
|
x, y, w, h = geom_rect.x, geom_rect.y, geom_rect.width, geom_rect.height
|
||||||
|
|
||||||
|
if not self.is_maximized() and not self.isfullscreen:
|
||||||
|
if self.guake_side == "top":
|
||||||
|
new_x = (w - (window_w + ((w - window_w)/2) )) + x
|
||||||
|
new_y = y
|
||||||
|
if self.guake_side == "bottom":
|
||||||
|
new_x = (w - (window_w + ((w - window_w)/2) )) + x
|
||||||
|
new_y = (h - window_h) + y
|
||||||
|
if self.guake_side == "left":
|
||||||
|
new_x = x
|
||||||
|
new_y = (h - (window_h + ((h - window_h)/2) )) + y
|
||||||
|
if self.guake_side == "right":
|
||||||
|
new_x = (w - window_w) + x
|
||||||
|
new_y = (h - (window_h + ((h - window_h)/2) )) + y
|
||||||
|
else:
|
||||||
|
new_x = x
|
||||||
|
new_y = y
|
||||||
|
|
||||||
|
self.move(new_x, new_y)
|
||||||
|
|
||||||
def register_callbacks(self):
|
def register_callbacks(self):
|
||||||
"""Connect the GTK+ signals we care about"""
|
"""Connect the GTK+ signals we care about"""
|
||||||
self.connect('key-press-event', self.on_key_press)
|
self.connect('key-press-event', self.on_key_press)
|
||||||
@ -129,22 +190,29 @@ class Window(Container, Gtk.Window):
|
|||||||
self.connect('focus-out-event', self.on_focus_out)
|
self.connect('focus-out-event', self.on_focus_out)
|
||||||
self.connect('focus-in-event', self.on_focus_in)
|
self.connect('focus-in-event', self.on_focus_in)
|
||||||
|
|
||||||
|
if self.guake_key not in ('', None):
|
||||||
|
guake_unload_id = self.connect('visibility-notify-event', self._bind_window_to_position)
|
||||||
|
|
||||||
|
_hide_key = self.config['keybindings']['hide_window']
|
||||||
|
toggle_key = self.guake_key if self.guake_key not in ('', None) else _hide_key if _hide_key not in ('', None) else None
|
||||||
|
|
||||||
# Attempt to grab a global hotkey for hiding the window.
|
# Attempt to grab a global hotkey for hiding the window.
|
||||||
# If we fail, we'll never hide the window, iconifying instead.
|
# If we fail, we'll never hide the window, iconifying instead.
|
||||||
if self.config['keybindings']['hide_window'] not in ('', None):
|
if toggle_key and display_manager() == 'X11':
|
||||||
if display_manager() == 'X11':
|
try:
|
||||||
try:
|
self.hidebound = Keybinder.bind(toggle_key, self.on_hide_window)
|
||||||
self.hidebound = Keybinder.bind(
|
except (KeyError, NameError):
|
||||||
self.config['keybindings']['hide_window'],
|
...
|
||||||
self.on_hide_window)
|
|
||||||
except (KeyError, NameError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not self.hidebound:
|
if not self.hidebound:
|
||||||
err('Unable to bind hide_window key, another instance/window has it.')
|
err('Unable to bind hide_window key, another instance/window has it.')
|
||||||
self.hidefunc = self.iconify
|
self.hidefunc = self.iconify
|
||||||
else:
|
|
||||||
self.hidefunc = self.hide
|
if self.guake_key not in ('', None):
|
||||||
|
GObject.signal_handler_disconnect(self, guake_unload_id)
|
||||||
|
self.set_decorated(True)
|
||||||
|
else:
|
||||||
|
self.hidefunc = self.hide
|
||||||
|
|
||||||
def apply_config(self):
|
def apply_config(self):
|
||||||
"""Apply various configuration options"""
|
"""Apply various configuration options"""
|
||||||
@ -294,7 +362,7 @@ class Window(Container, Gtk.Window):
|
|||||||
def confirm_close(self, window, type):
|
def confirm_close(self, window, type):
|
||||||
"""Display a confirmation dialog when the user is closing multiple
|
"""Display a confirmation dialog when the user is closing multiple
|
||||||
terminals in one window"""
|
terminals in one window"""
|
||||||
|
|
||||||
return(not (self.construct_confirm_close(window, type) == Gtk.ResponseType.ACCEPT))
|
return(not (self.construct_confirm_close(window, type) == Gtk.ResponseType.ACCEPT))
|
||||||
|
|
||||||
def on_destroy_event(self, widget, data=None):
|
def on_destroy_event(self, widget, data=None):
|
||||||
@ -342,7 +410,7 @@ class Window(Container, Gtk.Window):
|
|||||||
# pylint: disable-msg=W0613
|
# pylint: disable-msg=W0613
|
||||||
def on_window_state_changed(self, window, event):
|
def on_window_state_changed(self, window, event):
|
||||||
"""Handle the state of the window changing"""
|
"""Handle the state of the window changing"""
|
||||||
self.isfullscreen = bool(event.new_window_state &
|
self.isfullscreen = bool(event.new_window_state &
|
||||||
Gdk.WindowState.FULLSCREEN)
|
Gdk.WindowState.FULLSCREEN)
|
||||||
self.ismaximised = bool(event.new_window_state &
|
self.ismaximised = bool(event.new_window_state &
|
||||||
Gdk.WindowState.MAXIMIZED)
|
Gdk.WindowState.MAXIMIZED)
|
||||||
@ -401,7 +469,7 @@ class Window(Container, Gtk.Window):
|
|||||||
visual = screen.get_rgba_visual()
|
visual = screen.get_rgba_visual()
|
||||||
if visual:
|
if visual:
|
||||||
self.set_visual(visual)
|
self.set_visual(visual)
|
||||||
|
|
||||||
def show(self, startup=False):
|
def show(self, startup=False):
|
||||||
"""Undo the startup show request if started in hidden mode"""
|
"""Undo the startup show request if started in hidden mode"""
|
||||||
#Present is necessary to grab focus when window is hidden from taskbar.
|
#Present is necessary to grab focus when window is hidden from taskbar.
|
||||||
@ -491,7 +559,7 @@ class Window(Container, Gtk.Window):
|
|||||||
container = maker.make('VPaned')
|
container = maker.make('VPaned')
|
||||||
else:
|
else:
|
||||||
container = maker.make('HPaned')
|
container = maker.make('HPaned')
|
||||||
|
|
||||||
self.set_pos_by_ratio = True
|
self.set_pos_by_ratio = True
|
||||||
|
|
||||||
if not sibling:
|
if not sibling:
|
||||||
@ -515,7 +583,7 @@ class Window(Container, Gtk.Window):
|
|||||||
for term in order:
|
for term in order:
|
||||||
container.add(term)
|
container.add(term)
|
||||||
container.show_all()
|
container.show_all()
|
||||||
|
|
||||||
while Gtk.events_pending():
|
while Gtk.events_pending():
|
||||||
Gtk.main_iteration_do(False)
|
Gtk.main_iteration_do(False)
|
||||||
sibling.grab_focus()
|
sibling.grab_focus()
|
||||||
@ -563,7 +631,7 @@ class Window(Container, Gtk.Window):
|
|||||||
self.set_property('term_zoomed', True)
|
self.set_property('term_zoomed', True)
|
||||||
|
|
||||||
if font_scale:
|
if font_scale:
|
||||||
widget.cnxids.new(widget, 'size-allocate',
|
widget.cnxids.new(widget, 'size-allocate',
|
||||||
widget.zoom_scale, self.zoom_data)
|
widget.zoom_scale, self.zoom_data)
|
||||||
|
|
||||||
widget.grab_focus()
|
widget.grab_focus()
|
||||||
@ -636,7 +704,7 @@ class Window(Container, Gtk.Window):
|
|||||||
|
|
||||||
def get_terminals(self):
|
def get_terminals(self):
|
||||||
return(util.enumerate_descendants(self)[1])
|
return(util.enumerate_descendants(self)[1])
|
||||||
|
|
||||||
def get_visible_terminals(self):
|
def get_visible_terminals(self):
|
||||||
"""Walk down the widget tree to find all of the visible terminals.
|
"""Walk down the widget tree to find all of the visible terminals.
|
||||||
Mostly using Container::get_visible_terminals()"""
|
Mostly using Container::get_visible_terminals()"""
|
||||||
@ -726,7 +794,7 @@ class Window(Container, Gtk.Window):
|
|||||||
extra_height = win_height - total_font_height
|
extra_height = win_height - total_font_height
|
||||||
|
|
||||||
dbg('setting geometry hints: (ewidth:%s)(eheight:%s),\
|
dbg('setting geometry hints: (ewidth:%s)(eheight:%s),\
|
||||||
(fwidth:%s)(fheight:%s)' % (extra_width, extra_height,
|
(fwidth:%s)(fheight:%s)' % (extra_width, extra_height,
|
||||||
font_width, font_height))
|
font_width, font_height))
|
||||||
geometry = Gdk.Geometry()
|
geometry = Gdk.Geometry()
|
||||||
geometry.base_width = extra_width
|
geometry.base_width = extra_width
|
||||||
@ -850,7 +918,7 @@ class Window(Container, Gtk.Window):
|
|||||||
if not maker.isinstance(notebook, 'Notebook'):
|
if not maker.isinstance(notebook, 'Notebook'):
|
||||||
dbg('note in a notebook, refusing to ungroup tab')
|
dbg('note in a notebook, refusing to ungroup tab')
|
||||||
return
|
return
|
||||||
|
|
||||||
self.set_groups(None, self.get_visible_terminals())
|
self.set_groups(None, self.get_visible_terminals())
|
||||||
|
|
||||||
def move_tab(self, widget, direction):
|
def move_tab(self, widget, direction):
|
||||||
@ -883,7 +951,7 @@ class Window(Container, Gtk.Window):
|
|||||||
else:
|
else:
|
||||||
err('unknown direction: %s' % direction)
|
err('unknown direction: %s' % direction)
|
||||||
return
|
return
|
||||||
|
|
||||||
notebook.reorder_child(child, page)
|
notebook.reorder_child(child, page)
|
||||||
|
|
||||||
def navigate_terminal(self, terminal, direction):
|
def navigate_terminal(self, terminal, direction):
|
||||||
|
Loading…
Reference in New Issue
Block a user