Skip to content

Commit 55eb537

Browse files
committed
Added root terminal to Domains tray icon menu
1 parent 3d5af8f commit 55eb537

File tree

1 file changed

+68
-6
lines changed

1 file changed

+68
-6
lines changed

qui/tray/domains.py

+68-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import qui.utils
1919

2020
gi.require_version("Gtk", "3.0") # isort:skip
21-
from gi.repository import Gio, Gtk, GLib, GdkPixbuf # isort:skip
21+
from gi.repository import Gdk, Gio, Gtk, GLib, GdkPixbuf, GObject # isort:skip
2222

2323
import gbulb
2424

@@ -108,7 +108,11 @@ def __init__(self, label, img=None, icon_cache=None, icon_name=None):
108108
box.pack_start(placeholder, False, False, 0)
109109

110110
# Add a label to the menu item
111-
label_widget = Gtk.Label(label=label, xalign=0)
111+
label_widget = label
112+
if isinstance(label_widget, Gtk.Label):
113+
label_widget.set_xalign(0)
114+
else:
115+
label_widget = Gtk.Label(label=label, xalign=0)
112116
box.pack_start(label_widget, True, True, 0)
113117

114118
# Add the box to the menu item
@@ -289,17 +293,38 @@ async def perform_action(self):
289293
class RunTerminalItem(VMActionMenuItem):
290294
"""Run Terminal menu Item. When activated runs a terminal emulator."""
291295

292-
def __init__(self, vm, icon_cache):
296+
__gsignals__ = {
297+
'set-terminal-user-root': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (bool,)),
298+
}
299+
300+
def __init__(self, vm, icon_cache, as_root = False):
301+
label = Gtk.Label(RunTerminalItem.dynamic_label(as_root))
293302
super().__init__(
294303
vm,
295-
label=_("Run Terminal"),
304+
label=label,
296305
icon_cache=icon_cache,
297306
icon_name="terminal",
298307
)
308+
self.as_root = as_root
309+
self.label = label
310+
self.connect('set-terminal-user-root', self.set_as_root)
311+
312+
def dynamic_label(as_root):
313+
if as_root:
314+
return _("Run Root Terminal")
315+
else:
316+
return _("Run Terminal")
317+
318+
def set_as_root(self, _item, as_root):
319+
self.as_root = as_root
320+
self.label.set_text(RunTerminalItem.dynamic_label(as_root))
299321

300322
async def perform_action(self):
323+
service_args = {}
324+
if self.as_root:
325+
service_args['user'] = 'root'
301326
try:
302-
self.vm.run_service("qubes.StartApp+qubes-run-terminal")
327+
self.vm.run_service("qubes.StartApp+qubes-run-terminal", **service_args)
303328
except exc.QubesException as ex:
304329
show_error(
305330
_("Error starting terminal"),
@@ -361,7 +386,7 @@ def __init__(self, vm, app, icon_cache):
361386
self.app = app
362387

363388
self.add(OpenFileManagerItem(self.vm, icon_cache))
364-
self.add(RunTerminalItem(self.vm, icon_cache))
389+
self.add(RunTerminalItem(self.vm, icon_cache, as_root = app.terminal_as_root))
365390
self.add(PreferencesItem(self.vm, icon_cache))
366391
self.add(PauseItem(self.vm, icon_cache))
367392
self.add(ShutdownItem(self.vm, icon_cache))
@@ -562,6 +587,8 @@ def _set_submenu(self, state):
562587
submenu = PausedMenu(self.vm, self.icon_cache)
563588
else:
564589
submenu = DebugMenu(self.vm, self.icon_cache)
590+
submenu.connect('key-press-event', self.app.key_event)
591+
submenu.connect('key-release-event', self.app.key_event)
565592
# This is a workaround for a bug in Gtk which occurs when a
566593
# submenu is replaced while it is open.
567594
# see https://gitlab.gnome.org/GNOME/gtk/issues/885
@@ -637,6 +664,8 @@ def __init__(self, app_name, qapp, dispatcher, stats_dispatcher):
637664

638665
self.tray_menu = Gtk.Menu()
639666
self.tray_menu.set_reserve_toggle_size(False)
667+
self.tray_menu.connect('key-press-event', self.key_event)
668+
self.tray_menu.connect('key-release-event', self.key_event)
640669

641670
self.icon_cache = IconCache()
642671

@@ -704,6 +733,7 @@ def register_events(self):
704733
self.stats_dispatcher.add_handler("vm-stats", self.update_stats)
705734

706735
def show_menu(self, _unused, event):
736+
self.terminal_as_root = False
707737
self.tray_menu.popup_at_pointer(event) # None means current event
708738

709739
def emit_notification(self, vm, event, **kwargs):
@@ -1055,6 +1085,38 @@ def _disconnect_signals(self, _event):
10551085

10561086
self.stats_dispatcher.remove_handler("vm-stats", self.update_stats)
10571087

1088+
@property
1089+
def terminal_as_root(self):
1090+
try:
1091+
return self._terminal_as_root
1092+
except AttributeError:
1093+
self._terminal_as_root = False
1094+
return self.terminal_as_root
1095+
1096+
@terminal_as_root.setter
1097+
def terminal_as_root(self, as_root):
1098+
if as_root == self.terminal_as_root:
1099+
return
1100+
1101+
self._terminal_as_root = as_root
1102+
for item in self.menu_items.values():
1103+
if item.vm:
1104+
submenu = item.get_submenu()
1105+
if submenu is None:
1106+
continue
1107+
def do_emit(child):
1108+
try:
1109+
child.emit('set-terminal-user-root', as_root)
1110+
except Exception: # pylint: disable=broad-except
1111+
pass
1112+
submenu.foreach(do_emit)
1113+
1114+
def key_event(self, _unused, event):
1115+
if event.keyval in [Gdk.KEY_Shift_L, Gdk.KEY_Shift_R]:
1116+
if event.type == Gdk.EventType.KEY_PRESS:
1117+
self.terminal_as_root = True
1118+
elif event.type == Gdk.EventType.KEY_RELEASE:
1119+
self.terminal_as_root = False
10581120

10591121
def main():
10601122
"""main function"""

0 commit comments

Comments
 (0)