Skip to content

Commit 77147b2

Browse files
committed
Add signal handlers to show menus
1 parent 5902fa1 commit 77147b2

File tree

5 files changed

+63
-9
lines changed

5 files changed

+63
-9
lines changed

qui/clipboard.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
import math
3232
import os
3333
import fcntl
34+
import signal
3435
import qubesadmin
3536
import qubesadmin.events
37+
from functools import partial
3638

3739
import gi
3840
gi.require_version('Gtk', '3.0') # isort:skip
@@ -302,6 +304,11 @@ def _convert_to_readable(key: str):
302304
return key.upper()
303305
return key
304306

307+
def signal_handler(app, _signum, _frame):
308+
event = Gdk.EventButton()
309+
event.button = 1
310+
app.show_menu(None, event)
311+
305312
def main():
306313
loop = asyncio.get_event_loop()
307314
wm = pyinotify.WatchManager()
@@ -314,6 +321,9 @@ def main():
314321
handler = EventHandler(loop=loop, gtk_app=gtk_app)
315322
pyinotify.AsyncioNotifier(wm, loop, default_proc_fun=handler)
316323

324+
signal_handler_wrapper = partial(signal_handler, gtk_app)
325+
signal.signal(signal.SIGUSR1, signal_handler_wrapper)
326+
317327
return run_asyncio_and_show_errors(loop, [asyncio.ensure_future(
318328
dispatcher.listen_for_events())], _("Qubes Clipboard Widget"))
319329

qui/devices/device_widget.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
# You should have received a copy of the GNU Lesser General Public License along
1919
# with this program; if not, see <http://www.gnu.org/licenses/>.
2020
from typing import Set, List, Dict
21+
from functools import partial
2122
import asyncio
2223
import sys
2324
import time
25+
import signal
2426

2527
import importlib.resources
2628

@@ -294,7 +296,7 @@ def load_css(widget) -> str:
294296

295297
return theme
296298

297-
def show_menu(self, _unused, _event):
299+
def show_menu(self, _unused, event):
298300
"""Show menu at mouse pointer."""
299301
tray_menu = Gtk.Menu()
300302
theme = self.load_css(tray_menu)
@@ -333,7 +335,7 @@ def show_menu(self, _unused, _event):
333335
tray_menu.add(item)
334336

335337
tray_menu.show_all()
336-
tray_menu.popup_at_pointer(None) # use current event
338+
tray_menu.popup_at_pointer(event)
337339

338340
def emit_notification(self, title, message, priority, error=False,
339341
notification_id=None):
@@ -347,6 +349,12 @@ def emit_notification(self, title, message, priority, error=False,
347349
self.send_notification(notification_id, notification)
348350

349351

352+
def signal_handler(app, _signum, _frame):
353+
event = Gdk.EventButton()
354+
screen = Gdk.get_default_root_window().get_screen()
355+
event.window = screen.get_active_window()
356+
app.show_menu(None, event)
357+
350358
def main():
351359
qapp = qubesadmin.Qubes()
352360
# qapp = qubesadmin.tests.mock_app.MockQubesComplete()
@@ -355,6 +363,9 @@ def main():
355363
app = DevicesTray(
356364
'org.qubes.qui.tray.Devices', qapp, dispatcher)
357365

366+
signal_handler_wrapper = partial(signal_handler, app)
367+
signal.signal(signal.SIGUSR1, signal_handler_wrapper)
368+
358369
loop = asyncio.get_event_loop()
359370
return_code = qui.utils.run_asyncio_and_show_errors(
360371
loop, [asyncio.ensure_future(dispatcher.listen_for_events())],

qui/tray/disk_space.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# pylint: disable=wrong-import-position,import-error
22
import sys
33
import subprocess
4+
import signal
45
from typing import List
6+
from functools import partial
57

68
import gi
79
gi.require_version('Gtk', '3.0') # isort:skip
8-
from gi.repository import Gtk, GObject, Gio, GLib # isort:skip
10+
from gi.repository import Gtk, GObject, Gio, GLib, Gdk # isort:skip
911
from qubesadmin import Qubes
1012
from qubesadmin.utils import size_to_human
1113
from qubesadmin import exc
@@ -358,8 +360,17 @@ def __init__(self, **properties):
358360

359361
GObject.timeout_add_seconds(120, self.refresh_icon)
360362

363+
signal_handler_wrapper = partial(self.__signal_handler)
364+
signal.signal(signal.SIGUSR1, signal_handler_wrapper)
365+
361366
Gtk.main()
362367

368+
def __signal_handler(self, _signum, _frame):
369+
event = Gdk.EventButton()
370+
screen = Gdk.get_default_root_window().get_screen()
371+
event.window = screen.get_active_window()
372+
self.make_menu(None, event)
373+
363374
def refresh_icon(self):
364375
pool_data = PoolUsageData(self.qubes_app)
365376
vm_data = VMUsageData(self.qubes_app)
@@ -418,7 +429,7 @@ def set_icon_state(self, pool_warning=None, vm_warning=None):
418429
self.icon.set_tooltip_markup(
419430
_('<b>Qubes Disk Space Monitor</b>\nView free disk space.'))
420431

421-
def make_menu(self, _unused, _event):
432+
def make_menu(self, _unused, event):
422433
pool_data = PoolUsageData(self.qubes_app)
423434
vm_data = VMUsageData(self.qubes_app)
424435

@@ -460,7 +471,7 @@ def make_menu(self, _unused, _event):
460471
menu.set_reserve_toggle_size(False)
461472

462473
menu.show_all()
463-
menu.popup_at_pointer(None) # use current event
474+
menu.popup_at_pointer(event)
464475

465476
@staticmethod
466477
def make_title_item(text):

qui/tray/domains.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import os
1010
import threading
1111
import traceback
12+
import signal
13+
from functools import partial
1214

1315
import qubesadmin
1416
import qubesadmin.events
@@ -19,7 +21,7 @@
1921

2022
import gi # isort:skip
2123
gi.require_version('Gtk', '3.0') # isort:skip
22-
from gi.repository import Gio, Gtk, GObject, GLib, GdkPixbuf # isort:skip
24+
from gi.repository import Gio, Gtk, GObject, GLib, GdkPixbuf, Gdk # isort:skip
2325

2426
import gbulb
2527
gbulb.install()
@@ -913,6 +915,12 @@ def _disconnect_signals(self, _event):
913915
self.stats_dispatcher.remove_handler('vm-stats', self.update_stats)
914916

915917

918+
def signal_handler(app, _signum, _frame):
919+
event = Gdk.EventButton()
920+
screen = Gdk.get_default_root_window().get_screen()
921+
event.window = screen.get_active_window()
922+
app.show_menu(None, event)
923+
916924
def main():
917925
''' main function '''
918926
qapp = qubesadmin.Qubes()
@@ -923,6 +931,9 @@ def main():
923931
'org.qubes.qui.tray.Domains', qapp, dispatcher, stats_dispatcher)
924932
app.run()
925933

934+
signal_handler_wrapper = partial(signal_handler, app)
935+
signal.signal(signal.SIGUSR1, signal_handler_wrapper)
936+
926937
loop = asyncio.get_event_loop()
927938
tasks = [
928939
asyncio.ensure_future(dispatcher.listen_for_events()),

qui/tray/updates.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import asyncio
77
import sys
88
import subprocess
9+
import signal
10+
from functools import partial
911

1012
import qubesadmin
1113
import qubesadmin.events
@@ -14,7 +16,7 @@
1416

1517
import gi # isort:skip
1618
gi.require_version('Gtk', '3.0') # isort:skip
17-
from gi.repository import Gtk, Gio # isort:skip
19+
from gi.repository import Gtk, Gio, Gdk # isort:skip
1820

1921
import gbulb
2022
gbulb.install()
@@ -105,12 +107,12 @@ def setup_menu(self):
105107

106108
self.tray_menu.show_all()
107109

108-
def show_menu(self, _unused, _event):
110+
def show_menu(self, _unused, event):
109111
self.tray_menu = Gtk.Menu()
110112

111113
self.setup_menu()
112114

113-
self.tray_menu.popup_at_pointer(None) # use current event
115+
self.tray_menu.popup_at_pointer(event)
114116

115117
@staticmethod
116118
def launch_updater(*_args, **_kwargs):
@@ -212,13 +214,22 @@ def update_indicator_state(self):
212214
self.widget_icon.set_visible(False)
213215

214216

217+
def signal_handler(app, _signum, _frame):
218+
event = Gdk.EventButton()
219+
screen = Gdk.get_default_root_window().get_screen()
220+
event.window = screen.get_active_window()
221+
app.show_menu(None, event)
222+
215223
def main():
216224
qapp = qubesadmin.Qubes()
217225
dispatcher = qubesadmin.events.EventsDispatcher(qapp)
218226
app = UpdatesTray(
219227
'org.qubes.qui.tray.Updates', qapp, dispatcher)
220228
app.run()
221229

230+
signal_handler_wrapper = partial(signal_handler, app)
231+
signal.signal(signal.SIGUSR1, signal_handler_wrapper)
232+
222233
loop = asyncio.get_event_loop()
223234

224235
return qui.utils.run_asyncio_and_show_errors(loop, [asyncio.ensure_future(

0 commit comments

Comments
 (0)