Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 68 additions & 6 deletions qui/tray/domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import qui.utils

gi.require_version("Gtk", "3.0") # isort:skip
from gi.repository import Gio, Gtk, GLib, GdkPixbuf # isort:skip
from gi.repository import Gdk, Gio, Gtk, GLib, GdkPixbuf # isort:skip

import gbulb

Expand Down Expand Up @@ -114,7 +114,11 @@ def __init__(self, label, img=None, icon_cache=None, icon_name=None):
box.pack_start(placeholder, False, False, 0)

# Add a label to the menu item
label_widget = Gtk.Label(label=label, xalign=0)
label_widget = label
if isinstance(label_widget, Gtk.Label):
label_widget.set_xalign(0)
else:
label_widget = Gtk.Label(label=label, xalign=0)
box.pack_start(label_widget, True, True, 0)

# Add the box to the menu item
Expand Down Expand Up @@ -295,17 +299,35 @@ async def perform_action(self):
class RunTerminalItem(VMActionMenuItem):
"""Run Terminal menu Item. When activated runs a terminal emulator."""

def __init__(self, vm, icon_cache):
def __init__(self, vm, icon_cache, as_root=False):
label = Gtk.Label(label=RunTerminalItem.dynamic_label(as_root))
super().__init__(
vm,
label=_("Run Terminal"),
label=label,
icon_cache=icon_cache,
icon_name="terminal",
)
self.as_root = as_root
self.label = label

@staticmethod
def dynamic_label(as_root):
if as_root:
return _("Run Root Terminal")
return _("Run Terminal")

def set_as_root(self, as_root):
self.as_root = as_root
self.label.set_text(RunTerminalItem.dynamic_label(self.as_root))

async def perform_action(self):
service_args = {}
if self.as_root:
service_args["user"] = "root"
try:
self.vm.run_service("qubes.StartApp+qubes-run-terminal")
self.vm.run_service(
"qubes.StartApp+qubes-run-terminal", **service_args
)
except exc.QubesException as ex:
show_error(
_("Error starting terminal"),
Expand Down Expand Up @@ -367,7 +389,9 @@ def __init__(self, vm, app, icon_cache):
self.app = app

self.add(OpenFileManagerItem(self.vm, icon_cache))
self.add(RunTerminalItem(self.vm, icon_cache))
self.add(
RunTerminalItem(self.vm, icon_cache, as_root=app.terminal_as_root)
)
self.add(PreferencesItem(self.vm, icon_cache))
self.add(PauseItem(self.vm, icon_cache))
self.add(ShutdownItem(self.vm, icon_cache))
Expand Down Expand Up @@ -563,6 +587,8 @@ def _set_submenu(self, state):
submenu = PausedMenu(self.vm, self.icon_cache)
else:
submenu = DebugMenu(self.vm, self.icon_cache)
submenu.connect("key-press-event", self.app.key_event)
submenu.connect("key-release-event", self.app.key_event)
# This is a workaround for a bug in Gtk which occurs when a
# submenu is replaced while it is open.
# see https://gitlab.gnome.org/GNOME/gtk/issues/885
Expand Down Expand Up @@ -651,6 +677,8 @@ def __init__(self, app_name, qapp, dispatcher, stats_dispatcher):
self.tray_menu.set_reserve_toggle_size(False)
self.fullscreen_window_hack = get_fullscreen_window_hack()
self.fullscreen_window_hack.show_for_widget(self.tray_menu)
self.tray_menu.connect("key-press-event", self.key_event)
self.tray_menu.connect("key-release-event", self.key_event)

self.icon_cache = IconCache()

Expand Down Expand Up @@ -718,6 +746,7 @@ def register_events(self):
self.stats_dispatcher.add_handler("vm-stats", self.update_stats)

def show_menu(self, _unused, event):
self.terminal_as_root = False
self.tray_menu.popup_at_pointer(event) # None means current event

def emit_notification(self, vm, event, **kwargs):
Expand Down Expand Up @@ -1069,6 +1098,39 @@ def _disconnect_signals(self, _event):

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

@property
def terminal_as_root(self):
try:
return self._terminal_as_root
except AttributeError:
self._terminal_as_root = False
return self.terminal_as_root

@terminal_as_root.setter
def terminal_as_root(self, as_root):
if as_root == self.terminal_as_root:
return

self._terminal_as_root = as_root
for item in self.menu_items.values():
if item.vm:
submenu = item.get_submenu()
if submenu is None:
continue

def do_emit(child):
if isinstance(child, RunTerminalItem):
child.set_as_root(as_root)

submenu.foreach(do_emit)

def key_event(self, _unused, event):
if event.keyval in [Gdk.KEY_Shift_L, Gdk.KEY_Shift_R]:
if event.type == Gdk.EventType.KEY_PRESS:
self.terminal_as_root = True
elif event.type == Gdk.EventType.KEY_RELEASE:
self.terminal_as_root = False


def main():
"""main function"""
Expand Down