From c547f6eec9f16d9b8cf4bef7ecc868720de24a7f Mon Sep 17 00:00:00 2001 From: Nikos Tsipinakis Date: Sat, 8 Jul 2017 13:19:46 +0300 Subject: [PATCH] Add force_xinerama option Since after the release a lot of downstream users will not be building from source, it makes a lot more sense to have an option to fall back to the Xinerama extension for those that are still on systems that do not support RandR. --- README.md | 1 + config.mk | 10 +------ docs/dunst.pod | 10 +++++++ dunstrc | 12 +++++++++ src/settings.c | 6 +++++ src/settings.h | 1 + src/x11/screen.c | 69 ++++++++++++++++++------------------------------ src/x11/screen.h | 1 - 8 files changed, 56 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index d592402..6a7cb2b 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Dunst is a highly configurable and lightweight notification daemon. Dunst has a number of build dependencies that must be present before attempting configuration. The names are different depending on [distribution](https://github.com/dunst-project/dunst/wiki/Dependencies): - dbus +- libxinerama - libxrandr - libxss - libxdg-basedir diff --git a/config.mk b/config.mk index a4a6178..3ebdb00 100644 --- a/config.mk +++ b/config.mk @@ -32,15 +32,7 @@ CFLAGS += -g --std=gnu99 -pedantic -Wall -Wno-overlength-strings -Os ${STATIC} pkg_config_packs := dbus-1 x11 xscrnsaver \ "glib-2.0 >= 2.36" gio-2.0 \ - pangocairo gdk-2.0 - -ifeq ($(MULTIMON), xrandr) -pkg_config_packs += xrandr -CFLAGS += -DXRANDR -else ifeq ($(MULTIMON), xinerama) -pkg_config_packs += xinerama -CFLAGS += -DXINERAMA -endif + pangocairo gdk-2.0 xrandr xinerama # check if we need libxdg-basedir ifeq (,$(findstring STATIC_CONFIG,$(CFLAGS))) diff --git a/docs/dunst.pod b/docs/dunst.pod index dc5da36..2600d98 100644 --- a/docs/dunst.pod +++ b/docs/dunst.pod @@ -430,6 +430,16 @@ WM_CLASS). There should be no need to modify this setting for regular use. Display a notification on startup. This is usually used for debugging and there shouldn't be any need to use this option. +=item B (values: [true/false], default: false) + +Use the Xinerama extension instead of RandR for multi-monitor support. This +setting is provided for compatibility with older nVidia drivers that do not +support RandR and using it on systems that support RandR is highly discouraged. + +By enabling this setting dunst will not be able to detect when a monitor is +connected or disconnected which might break follow mode if the screen layout +changes. + =back =head2 Shortcut section diff --git a/dunstrc b/dunstrc index 9f92edd..e9654b9 100644 --- a/dunstrc +++ b/dunstrc @@ -192,6 +192,18 @@ # automatically after a crash. startup_notification = false + ### Legacy + + # Use the Xinerama extension instead of RandR for multi-monitor support. + # This setting is provided for compatibility with older nVidia drivers that + # do not support RandR and using it on systems that support RandR is highly + # discouraged. + # + # By enabling this setting dunst will not be able to detect when a monitor + # is connected or disconnected which might break follow mode if the screen + # layout changes. + force_xinerama = false + # Experimental features that may or may not work correctly. Do not expect them # to have a consistent behaviour across releases. [experimental] diff --git a/src/settings.c b/src/settings.c index f137c86..ede5f0b 100644 --- a/src/settings.c +++ b/src/settings.c @@ -103,6 +103,12 @@ void load_settings(char *cmdline_config_path) "" ); + settings.force_xinerama = option_get_bool( + "global", + "force_xinerama", "-force_xinerama", false, + "Force the use of the Xinerama extension" + ); + settings.font = option_get_string( "global", "font", "-font/-fn", font, diff --git a/src/settings.h b/src/settings.h index 773eb48..cd44fdc 100644 --- a/src/settings.h +++ b/src/settings.h @@ -70,6 +70,7 @@ typedef struct _settings { keyboard_shortcut close_all_ks; keyboard_shortcut history_ks; keyboard_shortcut context_ks; + bool force_xinerama; } settings_t; extern settings_t settings; diff --git a/src/x11/screen.c b/src/x11/screen.c index efad643..3e75e0d 100644 --- a/src/x11/screen.c +++ b/src/x11/screen.c @@ -4,12 +4,9 @@ #include #include #include -#ifdef XRANDR #include #include -#elif XINERAMA #include -#endif #include #include #include @@ -26,7 +23,10 @@ int screens_len; bool dunst_follow_errored = false; -void x_update_screens_fallback(); +void randr_init(); +void randr_update(); +void xinerama_update(); +void screen_update_fallback(); static void x_follow_setup_error_handler(void); static int x_follow_tear_down_error_handler(void); static int FollowXErrorHandler(Display *display, XErrorEvent *e); @@ -59,6 +59,15 @@ static double get_xft_dpi_value() return dpi; } +void init_screens() { + if (!settings.force_xinerama) { + randr_init(); + randr_update(); + } else { + xinerama_update(); + } +} + void alloc_screen_ar(int n) { assert(n > 0); @@ -71,27 +80,26 @@ void alloc_screen_ar(int n) screens_len = n; } -#ifdef XRANDR int randr_event_base = 0; -void init_screens() +void randr_init() { int randr_error_base = 0; if (!XRRQueryExtension(xctx.dpy, &randr_event_base, &randr_error_base)) { - fprintf(stderr, "Dunst was compiled with RandR but RandR extension is missing."); - exit(1); + fprintf(stderr, "Could not initialize the RandR extension, falling back to single monitor mode.\n"); + return; } XRRSelectInput(xctx.dpy, RootWindow(xctx.dpy, DefaultScreen(xctx.dpy)), RRScreenChangeNotifyMask); - x_update_screens(); } -void x_update_screens() +void randr_update() { int n; XRRMonitorInfo *m = XRRGetMonitors(xctx.dpy, RootWindow(xctx.dpy, DefaultScreen(xctx.dpy)), true, &n); - if (n == -1) { - x_update_screens_fallback(); + if (m == NULL || n == -1) { + fprintf(stderr, "(RandR) Could not get screen info, falling back to single monitor mode\n"); + screen_update_fallback(); return; } @@ -116,23 +124,17 @@ static int autodetect_dpi(screen_info *scr) void screen_check_event(XEvent event) { if (event.type == randr_event_base + RRScreenChangeNotify) - x_update_screens(); + randr_update(); } -#elif XINERAMA - -void init_screens() -{ - x_update_screens(); -} - -void x_update_screens() +void xinerama_update() { int n; XineramaScreenInfo *info = XineramaQueryScreens(xctx.dpy, &n); if (!info) { - x_update_screens_fallback(); + fprintf(stderr, "(Xinerama) Could not get screen info, falling back to single monitor mode\n"); + screen_update_fallback(); return; } @@ -147,29 +149,8 @@ void x_update_screens() XFree(info); } -void screen_check_event(XEvent event) {} //No-op -#define autodetect_dpi(x) 0 - -#else - -void init_screens() -{ - x_update_screens_fallback(); -} - -void x_update_screens() -{ - x_update_screens_fallback(); -} - -void screen_check_event(XEvent event) {} //No-op - -#define autodetect_dpi(x) 0 - -#endif - -void x_update_screens_fallback() +void screen_update_fallback() { alloc_screen_ar(1); diff --git a/src/x11/screen.h b/src/x11/screen.h index f434c24..8b47142 100644 --- a/src/x11/screen.h +++ b/src/x11/screen.h @@ -22,7 +22,6 @@ typedef struct _screen_info { } screen_info; void init_screens(); -void x_update_screens(); void screen_check_event(XEvent event); screen_info *get_active_screen();