Skip to content

Commit

Permalink
Allow specifying monitor by name
Browse files Browse the repository at this point in the history
  • Loading branch information
alebastr committed Jan 10, 2024
1 parent fbabcc5 commit ee3b934
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 17 deletions.
4 changes: 2 additions & 2 deletions docs/dunst.5.pod
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ All experimental settings are marked with I<Experimental>

=item B<monitor> (default: 0)

Specifies on which monitor the notifications should be displayed in, count
starts at 0. See the B<follow> setting.
Specifies on which monitor the notifications should be displayed in, either by
name or by number, starting from 0. See the B<follow> setting.

=item B<follow> (values: [none/mouse/keyboard] default: none)

Expand Down
13 changes: 13 additions & 0 deletions src/option_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,19 @@ int string_parse_bool(const void *data, const char *s, void *ret)
return success;
}

// Parse a string that may represent an integer value
int string_parse_maybe_int(const void *data, const char *s, void *ret)
{
int *intval = (int *)data;
if (!safe_string_to_int(intval, s)) {
*intval = INT_MIN;
}

g_free(*(char**) ret);
*(char**) ret = g_strdup(s);
return true;
}

int get_setting_id(const char *key, const char *section) {
int error_code = 0;
int partial_match_id = -1;
Expand Down
1 change: 1 addition & 0 deletions src/option_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
int string_parse_enum(const void* data, const char *s, void * ret);
int string_parse_sepcolor(const void *data, const char *s, void *ret);
int string_parse_bool(const void *data, const char *s, void *ret);
int string_parse_maybe_int(const void *data, const char *s, void *ret);

void set_defaults();
void save_settings(struct ini *ini);
Expand Down
1 change: 1 addition & 0 deletions src/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct dimensions {
};

struct screen_info {
char *name;
int id;
int x;
int y;
Expand Down
3 changes: 2 additions & 1 deletion src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ struct settings {
int frame_width;
char *frame_color;
int startup_notification;
int monitor;
char *monitor;
int monitor_num;
double scale;
char *dmenu;
char **dmenu_cmd;
Expand Down
6 changes: 3 additions & 3 deletions src/settings_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,11 +906,11 @@ static const struct setting allowed_settings[] = {
.name = "monitor",
.section = "global",
.description = "On which monitor should the notifications be displayed",
.type = TYPE_INT,
.type = TYPE_CUSTOM,
.default_value = "0",
.value = &settings.monitor,
.parser = NULL,
.parser_data = NULL,
.parser = string_parse_maybe_int,
.parser_data = &settings.monitor_num,
},
{
.name = "title",
Expand Down
32 changes: 26 additions & 6 deletions src/wayland/wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,24 @@ static void output_handle_scale(void *data, struct wl_output *wl_output,
wake_up();
}

#ifdef WL_OUTPUT_NAME_SINCE_VERSION
static void output_handle_name(void *data, struct wl_output *wl_output,
const char *name) {
struct dunst_output *output = data;
output->name = g_strdup(name);
LOG_D("Output global %" PRIu32 " name %s", output->global_name, name);
}
#endif

static const struct wl_output_listener output_listener = {
.geometry = output_handle_geometry,
.mode = output_handle_mode,
.done = noop,
.scale = output_handle_scale,
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
.name = output_handle_name,
.description = noop,
#endif
};

static void create_output(struct wl_registry *registry, uint32_t global_name, uint32_t version) {
Expand All @@ -158,12 +171,16 @@ static void create_output(struct wl_registry *registry, uint32_t global_name, ui
return;
}

uint32_t max_version = 3;
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
max_version = WL_OUTPUT_NAME_SINCE_VERSION;
#endif
bool recreate_surface = false;
static int number = 0;
LOG_I("New output found - id %i", number);
output->global_name = global_name;
output->wl_output = wl_registry_bind(registry, global_name, &wl_output_interface, 3);

output->wl_output = wl_registry_bind(registry, global_name, &wl_output_interface,
CLAMP(version, 3, max_version));
output->scale = 1;
output->fullscreen = false;

Expand All @@ -190,8 +207,8 @@ static void destroy_output(struct dunst_output *output) {
}
wl_list_remove(&output->link);
wl_output_destroy(output->wl_output);
free(output->name);
free(output);
g_free(output->name);
g_free(output);
}

static void touch_handle_motion(void *data, struct wl_touch *wl_touch,
Expand Down Expand Up @@ -521,7 +538,8 @@ static void create_seat(struct wl_registry *registry, uint32_t global_name, uint
// Warning, can return NULL
static struct dunst_output *get_configured_output() {
int n = 0;
int target_monitor = settings.monitor;
int target_monitor = settings.monitor_num;
const char *name = settings.monitor;

struct dunst_output *first_output = NULL, *configured_output = NULL,
*tmp_output = NULL;
Expand All @@ -530,6 +548,8 @@ static struct dunst_output *get_configured_output() {
first_output = tmp_output;
if (n == target_monitor)
configured_output = tmp_output;
if (g_strcmp0(name, tmp_output->name) == 0)
configured_output = tmp_output;
n++;
}

Expand All @@ -540,7 +560,7 @@ static struct dunst_output *get_configured_output() {
switch (settings.f_mode){
case FOLLOW_NONE: ; // this semicolon is neccesary
if (!configured_output) {
LOG_W("Monitor %i doesn't exist, using focused monitor", settings.monitor);
LOG_W("Monitor %s doesn't exist, using focused monitor", settings.monitor);
}
return configured_output;
case FOLLOW_MOUSE:
Expand Down
34 changes: 29 additions & 5 deletions src/x11/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,21 @@ void init_screens(void)
}
}

void free_screen_ar(struct screen_info *scr, int len)
{
if (!scr)
return;

for (int i = 0; i < len; ++i) {
XFree(scr[i].name);
}
g_free(scr);
}

void alloc_screen_ar(int n)
{
assert(n > 0);
g_free(screens);
free_screen_ar(screens, screens_len);
screens = g_malloc0(n * sizeof(struct screen_info));
screens_len = n;
}
Expand Down Expand Up @@ -150,6 +161,7 @@ void randr_update(void)
alloc_screen_ar(n);

for (int i = 0; i < n; i++) {
screens[i].name = XGetAtomName(xctx.dpy, m[i].name);
screens[i].id = i;
screens[i].x = m[i].x;
screens[i].y = m[i].y;
Expand Down Expand Up @@ -202,8 +214,8 @@ void screen_update_fallback(void)
alloc_screen_ar(1);

int screen;
if (settings.monitor >= 0)
screen = settings.monitor;
if (settings.monitor_num >= 0)
screen = settings.monitor_num;
else
screen = DefaultScreen(xctx.dpy);

Expand Down Expand Up @@ -297,6 +309,16 @@ bool window_is_fullscreen(Window window)
return fs;
}

static int get_screen_by_name(const char *name, int defval)
{
for (int i = 0; i < screens_len; ++i) {
if (g_strcmp0(screens[i].name, name) == 0) {
return i;
}
}
return defval;
}

/*
* Select the screen on which the Window
* should be displayed.
Expand All @@ -307,8 +329,10 @@ const struct screen_info *get_active_screen(void)
bool force_follow_mouse = false;

if (settings.f_mode == FOLLOW_NONE) {
if (settings.monitor >= 0 && settings.monitor < screens_len) {
ret = settings.monitor;
if (settings.monitor_num >= 0 && settings.monitor_num < screens_len) {
ret = settings.monitor_num;
} else {
ret = get_screen_by_name(settings.monitor, 0);
}
goto sc_cleanup;
} else {
Expand Down
3 changes: 3 additions & 0 deletions test/setting.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ TEST test_dunstrc_defaults(void) {
ASSERT_EQm(message, a, b);
}
break;
} else if (allowed_settings[i].parser == string_parse_maybe_int) {
// not a number
break;
} // else fall through
case TYPE_TIME:
case TYPE_INT:;
Expand Down

0 comments on commit ee3b934

Please sign in to comment.