Use a GTK+ main loop, generate events in a thread

This commit is contained in:
Přemysl Eric Janouch 2020-09-22 18:32:41 +02:00
parent b8242ff3c2
commit e2d91aae1c
Signed by: p
GPG Key ID: A0420B94F92B9493
1 changed files with 32 additions and 26 deletions

View File

@ -37,6 +37,7 @@ namespace Wdmtg {
// --- Globals ----------------------------------------------------------------- // --- Globals -----------------------------------------------------------------
X.Display dpy; ///< X display handle X.Display dpy; ///< X display handle
int sync_base; ///< Sync extension base
X.ID idle_counter; ///< XSync IDLETIME counter X.ID idle_counter; ///< XSync IDLETIME counter
X.Sync.Value idle_timeout; ///< User idle timeout 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; bool show_version;
const OptionEntry[] options = { const OptionEntry[] options = {
{ "version", 'V', OptionFlags.IN_MAIN, OptionArg.NONE, ref show_version, { "version", 'V', OptionFlags.IN_MAIN, OptionArg.NONE, ref show_version,
@ -232,13 +255,11 @@ namespace Wdmtg {
exit_fatal ("locale not supported by Xlib"); exit_fatal ("locale not supported by Xlib");
try { try {
var ctx = new OptionContext (" - activity tracker"); Gtk.init_with_args (ref args, " - activity tracker", options, null);
ctx.set_help_enabled (true);
ctx.add_main_entries (options, null);
ctx.parse (ref args);
} catch (OptionError e) { } catch (OptionError e) {
exit_fatal ("option parsing failed: %s", e.message); exit_fatal ("option parsing failed: %s", e.message);
return 1; } catch (Error e) {
exit_fatal ("%s", e.message);
} }
if (show_version) { if (show_version) {
stdout.printf (Config.PROJECT_NAME + " " + Config.PROJECT_VERSION + "\n"); stdout.printf (Config.PROJECT_NAME + " " + Config.PROJECT_VERSION + "\n");
@ -258,7 +279,7 @@ namespace Wdmtg {
// by polling the XScreenSaverInfo::idle field, see // by polling the XScreenSaverInfo::idle field, see
// https://www.x.org/releases/X11R7.5/doc/man/man3/Xss.3.html // 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) if (0 == X.Sync.query_extension (dpy, out sync_base, out dummy)
|| 0 == X.Sync.initialize (dpy, out dummy, out dummy)) || 0 == X.Sync.initialize (dpy, out dummy, out dummy))
exit_fatal ("cannot initialize XSync"); exit_fatal ("cannot initialize XSync");
@ -336,26 +357,11 @@ namespace Wdmtg {
if ((rc = db.exec ("COMMIT", null, out errmsg)) != Sqlite.OK) if ((rc = db.exec ("COMMIT", null, out errmsg)) != Sqlite.OK)
exit_fatal ("%s: %s", db_path, errmsg); exit_fatal ("%s: %s", db_path, errmsg);
var loop = new MainLoop (); var generator = new Thread<void> ("generator", generate_events);
var channel = new IOChannel.unix_new (dpy.connection_number ()); // TODO: somehow read events from the async queue
channel.add_watch (IOCondition.IN, (source, condition) => { // TODO: listen for connections on the control socket
if (0 == (condition & IOCondition.IN)) Gtk.main ();
return true; generator.join ();
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 ();
return 0; return 0;
} }
} }