From e2d91aae1ccb256de9ec37fbb1cabb59bd22a32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Tue, 22 Sep 2020 18:32:41 +0200 Subject: [PATCH] Use a GTK+ main loop, generate events in a thread --- wdmtg.vala | 58 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/wdmtg.vala b/wdmtg.vala index 5fb3aec..95646c7 100644 --- a/wdmtg.vala +++ b/wdmtg.vala @@ -37,6 +37,7 @@ namespace Wdmtg { // --- Globals ----------------------------------------------------------------- X.Display dpy; ///< X display handle + int sync_base; ///< Sync extension base X.ID idle_counter; ///< XSync IDLETIME counter X.Sync.Value idle_timeout; ///< User idle timeout @@ -218,6 +219,28 @@ namespace Wdmtg { } } + void generate_events () { + var channel = new IOChannel.unix_new (dpy.connection_number ()); + var watch = channel.create_watch (IOCondition.IN); + watch.set_callback (() => { + X.Event ev = {0}; + while (0 != dpy.pending ()) { + if (0 != dpy.next_event (ref ev)) { + exit_fatal ("XNextEvent returned non-zero"); + } else if (ev.type == X.EventType.PropertyNotify) { + on_x_property_notify (&ev.xproperty); + } else if (ev.type == sync_base + X.Sync.EventType.AlarmNotify) { + on_x_alarm_notify ((X.Sync.AlarmNotifyEvent *) (&ev)); + } + } + return true; + }); + + var loop = new MainLoop (MainContext.get_thread_default ()); + watch.attach (loop.get_context ()); + loop.run (); + } + bool show_version; const OptionEntry[] options = { { "version", 'V', OptionFlags.IN_MAIN, OptionArg.NONE, ref show_version, @@ -232,13 +255,11 @@ namespace Wdmtg { exit_fatal ("locale not supported by Xlib"); try { - var ctx = new OptionContext (" - activity tracker"); - ctx.set_help_enabled (true); - ctx.add_main_entries (options, null); - ctx.parse (ref args); + Gtk.init_with_args (ref args, " - activity tracker", options, null); } catch (OptionError e) { exit_fatal ("option parsing failed: %s", e.message); - return 1; + } catch (Error e) { + exit_fatal ("%s", e.message); } if (show_version) { stdout.printf (Config.PROJECT_NAME + " " + Config.PROJECT_VERSION + "\n"); @@ -258,7 +279,7 @@ namespace Wdmtg { // by polling the XScreenSaverInfo::idle field, see // https://www.x.org/releases/X11R7.5/doc/man/man3/Xss.3.html - int sync_base, dummy; + int dummy; if (0 == X.Sync.query_extension (dpy, out sync_base, out dummy) || 0 == X.Sync.initialize (dpy, out dummy, out dummy)) exit_fatal ("cannot initialize XSync"); @@ -336,26 +357,11 @@ namespace Wdmtg { if ((rc = db.exec ("COMMIT", null, out errmsg)) != Sqlite.OK) exit_fatal ("%s: %s", db_path, errmsg); - var loop = new MainLoop (); - var channel = new IOChannel.unix_new (dpy.connection_number ()); - channel.add_watch (IOCondition.IN, (source, condition) => { - if (0 == (condition & IOCondition.IN)) - return true; - - X.Event ev = {0}; - while (0 != dpy.pending ()) { - if (0 != dpy.next_event (ref ev)) { - exit_fatal ("XNextEvent returned non-zero"); - } else if (ev.type == X.EventType.PropertyNotify) { - on_x_property_notify (&ev.xproperty); - } else if (ev.type == sync_base + X.Sync.EventType.AlarmNotify) { - on_x_alarm_notify ((X.Sync.AlarmNotifyEvent *) (&ev)); - } - } - return true; - }); - - loop.run (); + var generator = new Thread ("generator", generate_events); + // TODO: somehow read events from the async queue + // TODO: listen for connections on the control socket + Gtk.main (); + generator.join (); return 0; } }