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.
This commit is contained in:
Nikos Tsipinakis 2017-07-08 13:19:46 +03:00
parent 44ac026d97
commit c547f6eec9
8 changed files with 56 additions and 54 deletions

View File

@ -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): 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 - dbus
- libxinerama
- libxrandr - libxrandr
- libxss - libxss
- libxdg-basedir - libxdg-basedir

View File

@ -32,15 +32,7 @@ CFLAGS += -g --std=gnu99 -pedantic -Wall -Wno-overlength-strings -Os ${STATIC}
pkg_config_packs := dbus-1 x11 xscrnsaver \ pkg_config_packs := dbus-1 x11 xscrnsaver \
"glib-2.0 >= 2.36" gio-2.0 \ "glib-2.0 >= 2.36" gio-2.0 \
pangocairo gdk-2.0 pangocairo gdk-2.0 xrandr xinerama
ifeq ($(MULTIMON), xrandr)
pkg_config_packs += xrandr
CFLAGS += -DXRANDR
else ifeq ($(MULTIMON), xinerama)
pkg_config_packs += xinerama
CFLAGS += -DXINERAMA
endif
# check if we need libxdg-basedir # check if we need libxdg-basedir
ifeq (,$(findstring STATIC_CONFIG,$(CFLAGS))) ifeq (,$(findstring STATIC_CONFIG,$(CFLAGS)))

View File

@ -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 Display a notification on startup. This is usually used for debugging and there
shouldn't be any need to use this option. shouldn't be any need to use this option.
=item B<force_xinerama> (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 =back
=head2 Shortcut section =head2 Shortcut section

12
dunstrc
View File

@ -192,6 +192,18 @@
# automatically after a crash. # automatically after a crash.
startup_notification = false 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 # Experimental features that may or may not work correctly. Do not expect them
# to have a consistent behaviour across releases. # to have a consistent behaviour across releases.
[experimental] [experimental]

View File

@ -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( settings.font = option_get_string(
"global", "global",
"font", "-font/-fn", font, "font", "-font/-fn", font,

View File

@ -70,6 +70,7 @@ typedef struct _settings {
keyboard_shortcut close_all_ks; keyboard_shortcut close_all_ks;
keyboard_shortcut history_ks; keyboard_shortcut history_ks;
keyboard_shortcut context_ks; keyboard_shortcut context_ks;
bool force_xinerama;
} settings_t; } settings_t;
extern settings_t settings; extern settings_t settings;

View File

@ -4,12 +4,9 @@
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xresource.h> #include <X11/Xresource.h>
#ifdef XRANDR
#include <X11/extensions/randr.h> #include <X11/extensions/randr.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#elif XINERAMA
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#endif
#include <assert.h> #include <assert.h>
#include <glib.h> #include <glib.h>
#include <locale.h> #include <locale.h>
@ -26,7 +23,10 @@ int screens_len;
bool dunst_follow_errored = false; 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 void x_follow_setup_error_handler(void);
static int x_follow_tear_down_error_handler(void); static int x_follow_tear_down_error_handler(void);
static int FollowXErrorHandler(Display *display, XErrorEvent *e); static int FollowXErrorHandler(Display *display, XErrorEvent *e);
@ -59,6 +59,15 @@ static double get_xft_dpi_value()
return dpi; return dpi;
} }
void init_screens() {
if (!settings.force_xinerama) {
randr_init();
randr_update();
} else {
xinerama_update();
}
}
void alloc_screen_ar(int n) void alloc_screen_ar(int n)
{ {
assert(n > 0); assert(n > 0);
@ -71,27 +80,26 @@ void alloc_screen_ar(int n)
screens_len = n; screens_len = n;
} }
#ifdef XRANDR
int randr_event_base = 0; int randr_event_base = 0;
void init_screens() void randr_init()
{ {
int randr_error_base = 0; int randr_error_base = 0;
if (!XRRQueryExtension(xctx.dpy, &randr_event_base, &randr_error_base)) { if (!XRRQueryExtension(xctx.dpy, &randr_event_base, &randr_error_base)) {
fprintf(stderr, "Dunst was compiled with RandR but RandR extension is missing."); fprintf(stderr, "Could not initialize the RandR extension, falling back to single monitor mode.\n");
exit(1); return;
} }
XRRSelectInput(xctx.dpy, RootWindow(xctx.dpy, DefaultScreen(xctx.dpy)), RRScreenChangeNotifyMask); XRRSelectInput(xctx.dpy, RootWindow(xctx.dpy, DefaultScreen(xctx.dpy)), RRScreenChangeNotifyMask);
x_update_screens();
} }
void x_update_screens() void randr_update()
{ {
int n; int n;
XRRMonitorInfo *m = XRRGetMonitors(xctx.dpy, RootWindow(xctx.dpy, DefaultScreen(xctx.dpy)), true, &n); XRRMonitorInfo *m = XRRGetMonitors(xctx.dpy, RootWindow(xctx.dpy, DefaultScreen(xctx.dpy)), true, &n);
if (n == -1) { if (m == NULL || n == -1) {
x_update_screens_fallback(); fprintf(stderr, "(RandR) Could not get screen info, falling back to single monitor mode\n");
screen_update_fallback();
return; return;
} }
@ -116,23 +124,17 @@ static int autodetect_dpi(screen_info *scr)
void screen_check_event(XEvent event) void screen_check_event(XEvent event)
{ {
if (event.type == randr_event_base + RRScreenChangeNotify) if (event.type == randr_event_base + RRScreenChangeNotify)
x_update_screens(); randr_update();
} }
#elif XINERAMA void xinerama_update()
void init_screens()
{
x_update_screens();
}
void x_update_screens()
{ {
int n; int n;
XineramaScreenInfo *info = XineramaQueryScreens(xctx.dpy, &n); XineramaScreenInfo *info = XineramaQueryScreens(xctx.dpy, &n);
if (!info) { 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; return;
} }
@ -147,29 +149,8 @@ void x_update_screens()
XFree(info); XFree(info);
} }
void screen_check_event(XEvent event) {} //No-op
#define autodetect_dpi(x) 0 void screen_update_fallback()
#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()
{ {
alloc_screen_ar(1); alloc_screen_ar(1);

View File

@ -22,7 +22,6 @@ typedef struct _screen_info {
} screen_info; } screen_info;
void init_screens(); void init_screens();
void x_update_screens();
void screen_check_event(XEvent event); void screen_check_event(XEvent event);
screen_info *get_active_screen(); screen_info *get_active_screen();