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.
This commit is contained in:
Nikos Tsipinakis 2018-05-06 20:32:00 +03:00
parent c29b1a39fb
commit 90dd111970
3 changed files with 51 additions and 32 deletions

View File

@ -1,7 +1,5 @@
/* copyright 2012 - 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */ /* copyright 2012 - 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */
#define XLIB_ILLEGAL_ACCESS
#include "dunst.h" #include "dunst.h"
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -28,12 +26,6 @@
#define VERSION "version info needed" #define VERSION "version info needed"
#endif #endif
typedef struct _x11_source {
GSource source;
Display *dpy;
Window w;
} x11_source_t;
/* index of colors fit to urgency level */ /* index of colors fit to urgency level */
GMainLoop *mainloop = NULL; GMainLoop *mainloop = NULL;
@ -155,8 +147,6 @@ int dunst_main(int argc, char *argv[])
int owner_id = initdbus(); int owner_id = initdbus();
draw_setup();
if (settings.startup_notification) { if (settings.startup_notification) {
notification *n = notification_create(); notification *n = notification_create();
n->id = 0; n->id = 0;
@ -174,26 +164,7 @@ int dunst_main(int argc, char *argv[])
mainloop = g_main_loop_new(NULL, FALSE); mainloop = g_main_loop_new(NULL, FALSE);
GPollFD dpy_pollfd = { xctx.dpy->fd, draw_setup();
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);
guint pause_src = g_unix_signal_add(SIGUSR1, pause_signal, NULL); guint pause_src = g_unix_signal_add(SIGUSR1, pause_signal, NULL);
guint unpause_src = g_unix_signal_add(SIGUSR2, unpause_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(term_src);
g_source_remove(int_src); g_source_remove(int_src);
g_source_destroy(x11_source);
dbus_tear_down(owner_id); dbus_tear_down(owner_id);
teardown(); teardown();

View File

@ -33,6 +33,12 @@
#define WIDTH 400 #define WIDTH 400
#define HEIGHT 400 #define HEIGHT 400
struct x11_source {
GSource source;
Display *dpy;
Window w;
};
xctx_t xctx; xctx_t xctx;
bool dunst_grab_errored = false; bool dunst_grab_errored = false;
@ -309,6 +315,9 @@ static void x_handle_click(XEvent ev)
void x_free(void) void x_free(void)
{ {
if (xctx.screensaver_info)
XFree(xctx.screensaver_info);
if (xctx.dpy) if (xctx.dpy)
XCloseDisplay(xctx.dpy); XCloseDisplay(xctx.dpy);
} }
@ -453,6 +462,39 @@ static void x_set_wm(Window win)
PropModeReplace, (unsigned char *) data, 1L); 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 * Setup the window
*/ */
@ -497,6 +539,8 @@ window_x11 *x_win_create(void)
WIDTH, HEIGHT); WIDTH, HEIGHT);
win->c_ctx = cairo_create(win->root_surface); win->c_ctx = cairo_create(win->root_surface);
win->esrc = x_win_reg_source(win);
long root_event_mask = SubstructureNotifyMask; long root_event_mask = SubstructureNotifyMask;
if (settings.f_mode != FOLLOW_NONE) { if (settings.f_mode != FOLLOW_NONE) {
root_event_mask |= FocusChangeMask | PropertyChangeMask; root_event_mask |= FocusChangeMask | PropertyChangeMask;
@ -508,6 +552,9 @@ window_x11 *x_win_create(void)
void x_win_destroy(window_x11 *win) void x_win_destroy(window_x11 *win)
{ {
g_source_destroy(win->esrc);
g_source_unref(win->esrc);
cairo_destroy(win->c_ctx); cairo_destroy(win->c_ctx);
cairo_surface_destroy(win->root_surface); cairo_surface_destroy(win->root_surface);
XDestroyWindow(xctx.dpy, win->xwin); XDestroyWindow(xctx.dpy, win->xwin);

View File

@ -2,6 +2,8 @@
#ifndef DUNST_X_H #ifndef DUNST_X_H
#define DUNST_X_H #define DUNST_X_H
#define XLIB_ILLEGAL_ACCESS
#include <cairo.h> #include <cairo.h>
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -37,6 +39,7 @@ typedef struct {
Window xwin; Window xwin;
cairo_surface_t *root_surface; cairo_surface_t *root_surface;
cairo_t *c_ctx; cairo_t *c_ctx;
GSource *esrc;
int cur_screen; int cur_screen;
bool visible; bool visible;
struct dimensions dim; struct dimensions dim;