From 90dd111970e802e123aa93778ee7781e7494f1af Mon Sep 17 00:00:00 2001 From: Nikos Tsipinakis Date: Sun, 6 May 2018 20:32:00 +0300 Subject: [PATCH] Refactor x11 event source to handle multiple windows Move the code to register the x11 event source under x_win_create so multiple windows can be created and be properly registered as the event source. One more missing piece is that the callback functions are still using the global win variable and not getting the window from the source. --- src/dunst.c | 33 +-------------------------------- src/x11/x.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/x11/x.h | 3 +++ 3 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/dunst.c b/src/dunst.c index cea339b..5b8d155 100644 --- a/src/dunst.c +++ b/src/dunst.c @@ -1,7 +1,5 @@ /* copyright 2012 - 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */ -#define XLIB_ILLEGAL_ACCESS - #include "dunst.h" #include @@ -28,12 +26,6 @@ #define VERSION "version info needed" #endif -typedef struct _x11_source { - GSource source; - Display *dpy; - Window w; -} x11_source_t; - /* index of colors fit to urgency level */ GMainLoop *mainloop = NULL; @@ -155,8 +147,6 @@ int dunst_main(int argc, char *argv[]) int owner_id = initdbus(); - draw_setup(); - if (settings.startup_notification) { notification *n = notification_create(); n->id = 0; @@ -174,26 +164,7 @@ int dunst_main(int argc, char *argv[]) mainloop = g_main_loop_new(NULL, FALSE); - GPollFD dpy_pollfd = { xctx.dpy->fd, - G_IO_IN | G_IO_HUP | G_IO_ERR, 0 - }; - - GSourceFuncs x11_source_funcs = { - x_mainloop_fd_prepare, - x_mainloop_fd_check, - x_mainloop_fd_dispatch, - NULL, - NULL, - NULL - }; - - GSource *x11_source = - g_source_new(&x11_source_funcs, sizeof(x11_source_t)); - ((x11_source_t *) x11_source)->dpy = xctx.dpy; - ((x11_source_t *) x11_source)->w = win->xwin; - g_source_add_poll(x11_source, &dpy_pollfd); - - g_source_attach(x11_source, NULL); + draw_setup(); guint pause_src = g_unix_signal_add(SIGUSR1, pause_signal, NULL); guint unpause_src = g_unix_signal_add(SIGUSR2, unpause_signal, NULL); @@ -213,8 +184,6 @@ int dunst_main(int argc, char *argv[]) g_source_remove(term_src); g_source_remove(int_src); - g_source_destroy(x11_source); - dbus_tear_down(owner_id); teardown(); diff --git a/src/x11/x.c b/src/x11/x.c index 5856008..fdfe33c 100644 --- a/src/x11/x.c +++ b/src/x11/x.c @@ -33,6 +33,12 @@ #define WIDTH 400 #define HEIGHT 400 +struct x11_source { + GSource source; + Display *dpy; + Window w; +}; + xctx_t xctx; bool dunst_grab_errored = false; @@ -309,6 +315,9 @@ static void x_handle_click(XEvent ev) void x_free(void) { + if (xctx.screensaver_info) + XFree(xctx.screensaver_info); + if (xctx.dpy) XCloseDisplay(xctx.dpy); } @@ -453,6 +462,39 @@ static void x_set_wm(Window win) PropModeReplace, (unsigned char *) data, 1L); } +GSource* x_win_reg_source(window_x11 *win) +{ + GPollFD *dpy_pollfd = g_malloc0(sizeof(dpy_pollfd)); + + *dpy_pollfd = (GPollFD) { + xctx.dpy->fd, + G_IO_IN | G_IO_HUP | G_IO_ERR, 0 + }; + + // Static is necessary here because glib keeps the pointer and we need + // to keep the reference alive. + static GSourceFuncs xsrc_fn = { + x_mainloop_fd_prepare, + x_mainloop_fd_check, + x_mainloop_fd_dispatch, + NULL, + NULL, + NULL + }; + + struct x11_source *xsrc = (struct x11_source*) g_source_new(&xsrc_fn, + sizeof(struct x11_source)); + + xsrc->dpy = xctx.dpy; + xsrc->w = win->xwin; + + g_source_add_poll((GSource*) xsrc_fn, dpy_pollfd); + + g_source_attach((GSource*) xsrc, NULL); + + return (GSource*)xsrc; +} + /* * Setup the window */ @@ -497,6 +539,8 @@ window_x11 *x_win_create(void) WIDTH, HEIGHT); win->c_ctx = cairo_create(win->root_surface); + win->esrc = x_win_reg_source(win); + long root_event_mask = SubstructureNotifyMask; if (settings.f_mode != FOLLOW_NONE) { root_event_mask |= FocusChangeMask | PropertyChangeMask; @@ -508,6 +552,9 @@ window_x11 *x_win_create(void) void x_win_destroy(window_x11 *win) { + g_source_destroy(win->esrc); + g_source_unref(win->esrc); + cairo_destroy(win->c_ctx); cairo_surface_destroy(win->root_surface); XDestroyWindow(xctx.dpy, win->xwin); diff --git a/src/x11/x.h b/src/x11/x.h index 0062359..ef1c412 100644 --- a/src/x11/x.h +++ b/src/x11/x.h @@ -2,6 +2,8 @@ #ifndef DUNST_X_H #define DUNST_X_H +#define XLIB_ILLEGAL_ACCESS + #include #include #include @@ -37,6 +39,7 @@ typedef struct { Window xwin; cairo_surface_t *root_surface; cairo_t *c_ctx; + GSource *esrc; int cur_screen; bool visible; struct dimensions dim;