diff --git a/src/draw.c b/src/draw.c index ad389b6..410e918 100644 --- a/src/draw.c +++ b/src/draw.c @@ -31,8 +31,7 @@ typedef struct { notification *n; } colored_layout; -cairo_surface_t *root_surface; -cairo_t *c_context; +window_x11 *win; PangoFontDescription *pango_fdesc; @@ -40,8 +39,7 @@ void draw_setup(void) { x_setup(); - root_surface = x_create_cairo_surface(); - c_context = cairo_create(root_surface); + win = x_win_create(); pango_fdesc = pango_font_description_from_string(settings.font); } @@ -555,7 +553,7 @@ static void calc_window_pos(int width, int height, int *ret_x, int *ret_y) void draw(void) { - GSList *layouts = create_layouts(c_context); + GSList *layouts = create_layouts(win->c_ctx); struct dimensions dim = calculate_dimensions(layouts); int width = dim.w; @@ -566,7 +564,7 @@ void draw(void) calc_window_pos(dim.w, dim.h, &win_x, &win_y); x_win_move(win_x, win_y, width, height); - cairo_xlib_surface_set_size(root_surface, width, height); + cairo_xlib_surface_set_size(win->root_surface, width, height); bool first = true; for (GSList *iter = layouts; iter; iter = iter->next) { @@ -578,9 +576,9 @@ void draw(void) first = false; } - cairo_set_source_surface(c_context, image_surface, 0, 0); - cairo_paint(c_context); - cairo_show_page(c_context); + cairo_set_source_surface(win->c_ctx, image_surface, 0, 0); + cairo_paint(win->c_ctx); + cairo_show_page(win->c_ctx); XFlush(xctx.dpy); @@ -590,9 +588,7 @@ void draw(void) void draw_deinit(void) { - cairo_destroy(c_context); - cairo_surface_destroy(root_surface); - + x_win_destroy(win); x_free(); } /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ diff --git a/src/draw.h b/src/draw.h index de9fb28..3a3ea88 100644 --- a/src/draw.h +++ b/src/draw.h @@ -1,6 +1,9 @@ #ifndef DUNST_DRAW_H #define DUNST_DRAW_H +#include "src/x11/x.h" +extern window_x11 *win; // Temporary + void draw_setup(void); void draw(void); diff --git a/src/dunst.c b/src/dunst.c index 79e648c..cea339b 100644 --- a/src/dunst.c +++ b/src/dunst.c @@ -59,19 +59,19 @@ static gboolean run(void *data) static gint64 next_timeout = 0; - if (!xctx.win.visible && queues_length_displayed() > 0) { + if (!win->visible && queues_length_displayed() > 0) { x_win_show(); } - if (xctx.win.visible && queues_length_displayed() == 0) { + if (win->visible && queues_length_displayed() == 0) { x_win_hide(); } - if (xctx.win.visible) { + if (win->visible) { draw(); } - if (xctx.win.visible) { + if (win->visible) { gint64 now = time_monotonic_now(); gint64 sleep = queues_get_next_datachange(now); gint64 timeout_at = now + sleep; @@ -190,7 +190,7 @@ int dunst_main(int argc, char *argv[]) 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 = xctx.win.xwin; + ((x11_source_t *) x11_source)->w = win->xwin; g_source_add_poll(x11_source, &dpy_pollfd); g_source_attach(x11_source, NULL); diff --git a/src/x11/x.c b/src/x11/x.c index 731986c..d722b4b 100644 --- a/src/x11/x.c +++ b/src/x11/x.c @@ -43,13 +43,6 @@ static void x_shortcut_setup_error_handler(void); static int x_shortcut_tear_down_error_handler(void); static void setopacity(Window win, unsigned long opacity); static void x_handle_click(XEvent ev); -static void x_win_setup(void); - -cairo_surface_t *x_create_cairo_surface(void) -{ - return cairo_xlib_surface_create(xctx.dpy, - xctx.win.xwin, DefaultVisual(xctx.dpy, 0), WIDTH, HEIGHT); -} void x_win_move(int x, int y, int width, int height) { @@ -59,14 +52,14 @@ void x_win_move(int x, int y, int width, int height) /* move and resize */ if (x != window_dim.x || y != window_dim.y) { - XMoveWindow(xctx.dpy, xctx.win.xwin, x, y); + XMoveWindow(xctx.dpy, win->xwin, x, y); window_dim.x = x; window_dim.y = y; } if (width != window_dim.w || height != window_dim.h) { - XResizeWindow(xctx.dpy, xctx.win.xwin, width, height); + XResizeWindow(xctx.dpy, win->xwin, width, height); window_dim.h = height; window_dim.w = width; @@ -175,12 +168,12 @@ gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer switch (ev.type) { case Expose: - if (ev.xexpose.count == 0 && xctx.win.visible) { + if (ev.xexpose.count == 0 && win->visible) { draw(); } break; case ButtonRelease: - if (ev.xbutton.window == xctx.win.xwin) { + if (ev.xbutton.window == win->xwin) { x_handle_click(ev); wake_up(); } @@ -226,9 +219,9 @@ gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer wake_up(); break; case CreateNotify: - if (xctx.win.visible && + if (win->visible && ev.xcreatewindow.override_redirect == 0) - XRaiseWindow(xctx.dpy, xctx.win.xwin); + XRaiseWindow(xctx.dpy, win->xwin); break; case PropertyNotify: fullscreen_now = have_fullscreen_window(); @@ -242,10 +235,10 @@ gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer * same screen. PropertyNotify is only neccessary * to detect a focus change to another screen */ - && xctx.win.visible - && scr->id != xctx.win.cur_screen) { + && win->visible + && scr->id != win->cur_screen) { draw(); - xctx.win.cur_screen = scr->id; + win->cur_screen = scr->id; } break; default: @@ -362,7 +355,6 @@ void x_setup(void) xctx.screensaver_info = XScreenSaverAllocInfo(); init_screens(); - x_win_setup(); x_shortcut_grab(&settings.history_ks); } @@ -455,8 +447,9 @@ static void x_set_wm(Window win) /* * Setup the window */ -static void x_win_setup(void) +window_x11 *x_win_create(void) { + window_x11 *win = g_malloc0(sizeof(window_x11)); Window root; XSetWindowAttributes wa; @@ -470,7 +463,7 @@ static void x_win_setup(void) ButtonReleaseMask | FocusChangeMask| StructureNotifyMask; screen_info *scr = get_active_screen(); - xctx.win.xwin = XCreateWindow(xctx.dpy, + win->xwin = XCreateWindow(xctx.dpy, root, scr->x, scr->y, @@ -483,19 +476,34 @@ static void x_win_setup(void) CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - x_set_wm(xctx.win.xwin); + x_set_wm(win->xwin); settings.transparency = settings.transparency > 100 ? 100 : settings.transparency; - setopacity(xctx.win.xwin, + setopacity(win->xwin, (unsigned long)((100 - settings.transparency) * (0xffffffff / 100))); + win->root_surface = cairo_xlib_surface_create(xctx.dpy, win->xwin, + DefaultVisual(xctx.dpy, 0), + WIDTH, HEIGHT); + win->c_ctx = cairo_create(win->root_surface); long root_event_mask = SubstructureNotifyMask; if (settings.f_mode != FOLLOW_NONE) { root_event_mask |= FocusChangeMask | PropertyChangeMask; } XSelectInput(xctx.dpy, root, root_event_mask); + + return win; +} + +void x_win_destroy(window_x11 *win) +{ + cairo_destroy(win->c_ctx); + cairo_surface_destroy(win->root_surface); + XDestroyWindow(xctx.dpy, win->xwin); + + g_free(win); } /* @@ -504,7 +512,7 @@ static void x_win_setup(void) void x_win_show(void) { /* window is already mapped or there's nothing to show */ - if (xctx.win.visible || queues_length_displayed() == 0) { + if (win->visible || queues_length_displayed() == 0) { return; } @@ -516,7 +524,7 @@ void x_win_show(void) XGrabButton(xctx.dpy, AnyButton, AnyModifier, - xctx.win.xwin, + win->xwin, false, BUTTONMASK, GrabModeAsync, @@ -527,8 +535,8 @@ void x_win_show(void) LOG_W("Unable to grab mouse button(s)."); } - XMapRaised(xctx.dpy, xctx.win.xwin); - xctx.win.visible = true; + XMapRaised(xctx.dpy, win->xwin); + win->visible = true; } /* @@ -540,10 +548,10 @@ void x_win_hide(void) x_shortcut_ungrab(&settings.close_all_ks); x_shortcut_ungrab(&settings.context_ks); - XUngrabButton(xctx.dpy, AnyButton, AnyModifier, xctx.win.xwin); - XUnmapWindow(xctx.dpy, xctx.win.xwin); + XUngrabButton(xctx.dpy, AnyButton, AnyModifier, win->xwin); + XUnmapWindow(xctx.dpy, win->xwin); XFlush(xctx.dpy); - xctx.win.visible = false; + win->visible = false; } /* diff --git a/src/x11/x.h b/src/x11/x.h index 851be0a..606c092 100644 --- a/src/x11/x.h +++ b/src/x11/x.h @@ -36,6 +36,7 @@ struct dimensions { typedef struct { Window xwin; cairo_surface_t *root_surface; + cairo_t *c_ctx; int cur_screen; bool visible; struct dimensions dim; @@ -43,7 +44,6 @@ typedef struct { typedef struct _xctx { Display *dpy; - window_x11 win; const char *colors[3][3]; XScreenSaverInfo *screensaver_info; } xctx_t; @@ -57,9 +57,11 @@ typedef struct _color_t { extern xctx_t xctx; /* window */ +window_x11 *x_win_create(void); void x_win_move(int x, int y, int width, int height); void x_win_hide(void); void x_win_show(void); +void x_win_destroy(window_x11 *win); /* shortcut */ void x_shortcut_init(keyboard_shortcut *shortcut); @@ -74,8 +76,6 @@ void x_free(void); struct geometry x_parse_geometry(const char *geom_str); -cairo_surface_t *x_create_cairo_surface(void); - gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer user_data); gboolean x_mainloop_fd_check(GSource *source);