From a7fd3cb0ec9255ff5bc13cc614b714e946fda122 Mon Sep 17 00:00:00 2001 From: Nikos Tsipinakis Date: Tue, 6 Mar 2018 19:50:12 +0200 Subject: [PATCH] Move geometry handling to settings Change the value of geometry in settings from an unparsed string to a struct containing the properly parsed geometry info. Since we depend on X11 for geometry parsing this (unfortunately) introduces an X11 dependency on the settings module, this can only be resolved if we implement our own parsing. --- config.h | 10 ++++++- src/draw.c | 19 +++++++------ src/settings.c | 24 +++++++++++++---- src/settings.h | 14 +++++++++- src/x11/screen.h | 2 -- src/x11/x.c | 69 ++++++++++++++++++++++++++++-------------------- src/x11/x.h | 6 ++++- 7 files changed, 95 insertions(+), 49 deletions(-) diff --git a/config.h b/config.h index fc6a42b..e809ef9 100644 --- a/config.h +++ b/config.h @@ -16,7 +16,15 @@ settings_t defaults = { .icons = { "dialog-information", "dialog-information", "dialog-warning" }, /* low, normal, critical */ .transparency = 0, /* transparency */ -.geom = "0x0", /* geometry */ +.geometry = { .x = 0, /* geometry */ + .y = 0, + .w = 0, + .h = 0, + .negative_x = 0, + .negative_y = 0, + .negative_width = 0, + .width_set = 0 + }, .title = "Dunst", /* the title of dunst notification windows */ .class = "Dunst", /* the class of dunst notification windows */ .shrink = false, /* shrinking */ diff --git a/src/draw.c b/src/draw.c index 5306a2a..1e0899d 100644 --- a/src/draw.c +++ b/src/draw.c @@ -149,7 +149,7 @@ static void free_colored_layout(void *data) static bool have_dynamic_width(void) { - return (xctx.geometry.mask & WidthValue && xctx.geometry.w == 0); + return (settings.geometry.width_set && settings.geometry.w == 0); } static dimension_t calculate_dimensions(GSList *layouts) @@ -159,18 +159,17 @@ static dimension_t calculate_dimensions(GSList *layouts) dim.h = 0; dim.x = 0; dim.y = 0; - dim.mask = xctx.geometry.mask; screen_info *scr = get_active_screen(); if (have_dynamic_width()) { /* dynamic width */ dim.w = 0; - } else if (xctx.geometry.mask & WidthValue) { + } else if (settings.geometry.width_set) { /* fixed width */ - if (xctx.geometry.negative_width) { - dim.w = scr->dim.w - xctx.geometry.w; + if (settings.geometry.negative_width) { + dim.w = scr->dim.w - settings.geometry.w; } else { - dim.w = xctx.geometry.w; + dim.w = settings.geometry.w; } } else { /* across the screen */ @@ -202,8 +201,8 @@ static dimension_t calculate_dimensions(GSList *layouts) if (total_width > scr->dim.w) { /* set width to screen width */ - dim.w = scr->dim.w - xctx.geometry.x * 2; - } else if (have_dynamic_width() || (total_width < xctx.geometry.w && settings.shrink)) { + dim.w = scr->dim.w - settings.geometry.x * 2; + } else if (have_dynamic_width() || (total_width < settings.geometry.w && settings.shrink)) { /* set width to text width */ dim.w = total_width + 2 * settings.frame_width; } @@ -394,7 +393,7 @@ static GSList *r_create_layouts(cairo_t *c) notification_update_text_to_render(n); - if (!iter->next && xmore_is_needed && xctx.geometry.h == 1) { + if (!iter->next && xmore_is_needed && settings.geometry.h == 1) { char *new_ttr = g_strdup_printf("%s (%d more)", n->text_to_render, qlen); g_free(n->text_to_render); n->text_to_render = new_ttr; @@ -403,7 +402,7 @@ static GSList *r_create_layouts(cairo_t *c) r_create_layout_from_notification(c, n)); } - if (xmore_is_needed && xctx.geometry.h != 1) { + if (xmore_is_needed && settings.geometry.h != 1) { /* append xmore message as new message */ layouts = g_slist_append(layouts, r_create_layout_for_xmore(c, last, qlen)); diff --git a/src/settings.c b/src/settings.c index aa0109d..6e31d28 100644 --- a/src/settings.c +++ b/src/settings.c @@ -17,6 +17,7 @@ #include "notification.h" #include "option_parser.h" #include "utils.h" +#include "x11/x.h" settings_t settings; @@ -256,11 +257,24 @@ void load_settings(char *cmdline_config_path) "Define the class of windows spawned by dunst." ); - settings.geom = option_get_string( - "global", - "geometry", "-geom/-geometry", defaults.geom, - "Geometry for the window" - ); + { + + char *c = option_get_string( + "global", + "geometry", "-geom/-geometry", NULL, + "Geometry for the window" + ); + + if (c) { + // TODO: Implement own geometry parsing to get rid of + // the include dependency on X11 + settings.geometry = x_parse_geometry(c); + g_free(c); + } else { + settings.geometry = defaults.geometry; + } + + } settings.shrink = option_get_bool( "global", diff --git a/src/settings.h b/src/settings.h index 0577f42..50eb1c6 100644 --- a/src/settings.h +++ b/src/settings.h @@ -13,6 +13,18 @@ enum separator_color { FOREGROUND, AUTO, FRAME, CUSTOM }; enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD }; enum markup_mode { MARKUP_NULL, MARKUP_NO, MARKUP_STRIP, MARKUP_FULL }; +struct geometry { + int x; + int y; + unsigned int w; + unsigned int h; + bool negative_x; + bool negative_y; + bool negative_width; + bool width_set; + +}; + typedef struct _settings { bool print_notifications; bool per_monitor_dpi; @@ -33,7 +45,7 @@ typedef struct _settings { gint64 timeouts[3]; char *icons[3]; unsigned int transparency; - char *geom; + struct geometry geometry; char *title; char *class; int shrink; diff --git a/src/x11/screen.h b/src/x11/screen.h index fcd020d..33bd227 100644 --- a/src/x11/screen.h +++ b/src/x11/screen.h @@ -13,8 +13,6 @@ typedef struct _dimension_t { unsigned int h; unsigned int mmh; unsigned int w; - int mask; - int negative_width; } dimension_t; typedef struct _screen_info { diff --git a/src/x11/x.c b/src/x11/x.c index 1c5fb5a..34375b5 100644 --- a/src/x11/x.c +++ b/src/x11/x.c @@ -58,16 +58,16 @@ void x_win_move(int width, int height) screen_info *scr = get_active_screen(); xctx.cur_screen = scr->scr; /* calculate window position */ - if (xctx.geometry.mask & XNegative) { - x = (scr->dim.x + (scr->dim.w - width)) + xctx.geometry.x; + if (settings.geometry.negative_x) { + x = (scr->dim.x + (scr->dim.w - width)) + settings.geometry.x; } else { - x = scr->dim.x + xctx.geometry.x; + x = scr->dim.x + settings.geometry.x; } - if (xctx.geometry.mask & YNegative) { - y = scr->dim.y + (scr->dim.h + xctx.geometry.y) - height; + if (settings.geometry.negative_y) { + y = scr->dim.y + (scr->dim.h + settings.geometry.y) - height; } else { - y = scr->dim.y + xctx.geometry.y; + y = scr->dim.y + settings.geometry.y; } /* move and resize */ @@ -365,29 +365,6 @@ void x_setup(void) else xctx.colors[ColFrame][URG_CRIT] = settings.frame_color; - /* parse and set xctx.geometry and monitor position */ - if (settings.geom[0] == '-') { - xctx.geometry.negative_width = true; - settings.geom++; - } else { - xctx.geometry.negative_width = false; - } - - xctx.geometry.mask = XParseGeometry(settings.geom, - &xctx.geometry.x, &xctx.geometry.y, - &xctx.geometry.w, &xctx.geometry.h); - - /* calculate maximum notification count and push information to queue */ - if (xctx.geometry.h == 0) { - queues_displayed_limit(0); - } else if (xctx.geometry.h == 1) { - queues_displayed_limit(1); - } else if (settings.indicate_hidden) { - queues_displayed_limit(xctx.geometry.h - 1); - } else { - queues_displayed_limit(xctx.geometry.h); - } - xctx.screensaver_info = XScreenSaverAllocInfo(); init_screens(); @@ -395,6 +372,40 @@ void x_setup(void) x_shortcut_grab(&settings.history_ks); } +struct geometry x_parse_geometry(const char *geom_str) +{ + assert(geom_str); + + if (geom_str[0] == '-') { + settings.geometry.negative_width = true; + geom_str++; + } else { + settings.geometry.negative_width = false; + } + + struct geometry geometry = { 0 }; + + int mask = XParseGeometry(geom_str, + &geometry.x, &geometry.y, + &geometry.w, &geometry.h); + geometry.width_set = mask & WidthValue; + geometry.negative_x = mask & XNegative; + geometry.negative_y = mask & YNegative; + + /* calculate maximum notification count and push information to queue */ + if (geometry.h == 0) { + queues_displayed_limit(0); + } else if (geometry.h == 1) { + queues_displayed_limit(1); + } else if (settings.indicate_hidden) { + queues_displayed_limit(geometry.h - 1); + } else { + queues_displayed_limit(geometry.h); + } + + return geometry; +} + static void x_set_wm(Window win) { diff --git a/src/x11/x.h b/src/x11/x.h index da46389..96dd07c 100644 --- a/src/x11/x.h +++ b/src/x11/x.h @@ -23,13 +23,15 @@ typedef struct _keyboard_shortcut { bool is_valid; } keyboard_shortcut; +// Cyclical dependency +#include "src/settings.h" + typedef struct _xctx { Atom utf8; Display *dpy; int cur_screen; Window win; bool visible; - dimension_t geometry; const char *colors[3][3]; XScreenSaverInfo *screensaver_info; dimension_t window_dim; @@ -60,6 +62,8 @@ bool x_is_idle(void); void x_setup(void); 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,