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.
This commit is contained in:
Nikos Tsipinakis 2018-03-06 19:50:12 +02:00
parent 5895593d0b
commit a7fd3cb0ec
7 changed files with 95 additions and 49 deletions

View File

@ -16,7 +16,15 @@ settings_t defaults = {
.icons = { "dialog-information", "dialog-information", "dialog-warning" }, /* low, normal, critical */ .icons = { "dialog-information", "dialog-information", "dialog-warning" }, /* low, normal, critical */
.transparency = 0, /* transparency */ .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 */ .title = "Dunst", /* the title of dunst notification windows */
.class = "Dunst", /* the class of dunst notification windows */ .class = "Dunst", /* the class of dunst notification windows */
.shrink = false, /* shrinking */ .shrink = false, /* shrinking */

View File

@ -149,7 +149,7 @@ static void free_colored_layout(void *data)
static bool have_dynamic_width(void) 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) static dimension_t calculate_dimensions(GSList *layouts)
@ -159,18 +159,17 @@ static dimension_t calculate_dimensions(GSList *layouts)
dim.h = 0; dim.h = 0;
dim.x = 0; dim.x = 0;
dim.y = 0; dim.y = 0;
dim.mask = xctx.geometry.mask;
screen_info *scr = get_active_screen(); screen_info *scr = get_active_screen();
if (have_dynamic_width()) { if (have_dynamic_width()) {
/* dynamic width */ /* dynamic width */
dim.w = 0; dim.w = 0;
} else if (xctx.geometry.mask & WidthValue) { } else if (settings.geometry.width_set) {
/* fixed width */ /* fixed width */
if (xctx.geometry.negative_width) { if (settings.geometry.negative_width) {
dim.w = scr->dim.w - xctx.geometry.w; dim.w = scr->dim.w - settings.geometry.w;
} else { } else {
dim.w = xctx.geometry.w; dim.w = settings.geometry.w;
} }
} else { } else {
/* across the screen */ /* across the screen */
@ -202,8 +201,8 @@ static dimension_t calculate_dimensions(GSList *layouts)
if (total_width > scr->dim.w) { if (total_width > scr->dim.w) {
/* set width to screen width */ /* set width to screen width */
dim.w = scr->dim.w - xctx.geometry.x * 2; dim.w = scr->dim.w - settings.geometry.x * 2;
} else if (have_dynamic_width() || (total_width < xctx.geometry.w && settings.shrink)) { } else if (have_dynamic_width() || (total_width < settings.geometry.w && settings.shrink)) {
/* set width to text width */ /* set width to text width */
dim.w = total_width + 2 * settings.frame_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); 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); char *new_ttr = g_strdup_printf("%s (%d more)", n->text_to_render, qlen);
g_free(n->text_to_render); g_free(n->text_to_render);
n->text_to_render = new_ttr; 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)); 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 */ /* append xmore message as new message */
layouts = g_slist_append(layouts, layouts = g_slist_append(layouts,
r_create_layout_for_xmore(c, last, qlen)); r_create_layout_for_xmore(c, last, qlen));

View File

@ -17,6 +17,7 @@
#include "notification.h" #include "notification.h"
#include "option_parser.h" #include "option_parser.h"
#include "utils.h" #include "utils.h"
#include "x11/x.h"
settings_t settings; settings_t settings;
@ -256,12 +257,25 @@ void load_settings(char *cmdline_config_path)
"Define the class of windows spawned by dunst." "Define the class of windows spawned by dunst."
); );
settings.geom = option_get_string( {
char *c = option_get_string(
"global", "global",
"geometry", "-geom/-geometry", defaults.geom, "geometry", "-geom/-geometry", NULL,
"Geometry for the window" "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( settings.shrink = option_get_bool(
"global", "global",
"shrink", "-shrink", defaults.shrink, "shrink", "-shrink", defaults.shrink,

View File

@ -13,6 +13,18 @@ enum separator_color { FOREGROUND, AUTO, FRAME, CUSTOM };
enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD }; enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD };
enum markup_mode { MARKUP_NULL, MARKUP_NO, MARKUP_STRIP, MARKUP_FULL }; 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 { typedef struct _settings {
bool print_notifications; bool print_notifications;
bool per_monitor_dpi; bool per_monitor_dpi;
@ -33,7 +45,7 @@ typedef struct _settings {
gint64 timeouts[3]; gint64 timeouts[3];
char *icons[3]; char *icons[3];
unsigned int transparency; unsigned int transparency;
char *geom; struct geometry geometry;
char *title; char *title;
char *class; char *class;
int shrink; int shrink;

View File

@ -13,8 +13,6 @@ typedef struct _dimension_t {
unsigned int h; unsigned int h;
unsigned int mmh; unsigned int mmh;
unsigned int w; unsigned int w;
int mask;
int negative_width;
} dimension_t; } dimension_t;
typedef struct _screen_info { typedef struct _screen_info {

View File

@ -58,16 +58,16 @@ void x_win_move(int width, int height)
screen_info *scr = get_active_screen(); screen_info *scr = get_active_screen();
xctx.cur_screen = scr->scr; xctx.cur_screen = scr->scr;
/* calculate window position */ /* calculate window position */
if (xctx.geometry.mask & XNegative) { if (settings.geometry.negative_x) {
x = (scr->dim.x + (scr->dim.w - width)) + xctx.geometry.x; x = (scr->dim.x + (scr->dim.w - width)) + settings.geometry.x;
} else { } else {
x = scr->dim.x + xctx.geometry.x; x = scr->dim.x + settings.geometry.x;
} }
if (xctx.geometry.mask & YNegative) { if (settings.geometry.negative_y) {
y = scr->dim.y + (scr->dim.h + xctx.geometry.y) - height; y = scr->dim.y + (scr->dim.h + settings.geometry.y) - height;
} else { } else {
y = scr->dim.y + xctx.geometry.y; y = scr->dim.y + settings.geometry.y;
} }
/* move and resize */ /* move and resize */
@ -365,29 +365,6 @@ void x_setup(void)
else else
xctx.colors[ColFrame][URG_CRIT] = settings.frame_color; 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(); xctx.screensaver_info = XScreenSaverAllocInfo();
init_screens(); init_screens();
@ -395,6 +372,40 @@ void x_setup(void)
x_shortcut_grab(&settings.history_ks); 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) static void x_set_wm(Window win)
{ {

View File

@ -23,13 +23,15 @@ typedef struct _keyboard_shortcut {
bool is_valid; bool is_valid;
} keyboard_shortcut; } keyboard_shortcut;
// Cyclical dependency
#include "src/settings.h"
typedef struct _xctx { typedef struct _xctx {
Atom utf8; Atom utf8;
Display *dpy; Display *dpy;
int cur_screen; int cur_screen;
Window win; Window win;
bool visible; bool visible;
dimension_t geometry;
const char *colors[3][3]; const char *colors[3][3];
XScreenSaverInfo *screensaver_info; XScreenSaverInfo *screensaver_info;
dimension_t window_dim; dimension_t window_dim;
@ -60,6 +62,8 @@ bool x_is_idle(void);
void x_setup(void); void x_setup(void);
void x_free(void); void x_free(void);
struct geometry x_parse_geometry(const char *geom_str);
cairo_surface_t *x_create_cairo_surface(void); cairo_surface_t *x_create_cairo_surface(void);
gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback,