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,