Permalink
Browse files

Implement RandR 1.5 support (#2580)

This comes with the intentionally undocumented --disable-randr15 command
line flag and disable-randr15 configuration directive. We will add
documentation before the release if and only if it turns out that users
actually need to use this flag in their setups. Ideally, nobody would
need to use the flag and everything would just keep working, but it’s
better to be safe than sorry.

fixes #1799
  • Loading branch information...
stapelberg committed Nov 28, 2016
1 parent f2ffd8d commit 633a9f7b1475ffd5c72489bc6bd2d224c441c9a9
View
@@ -65,7 +65,7 @@ sub slurp {
my $current_state;
for my $line (@lines) {
- if (my ($state) = ($line =~ /^state ([A-Z_]+):$/)) {
+ if (my ($state) = ($line =~ /^state ([A-Z0-9_]+):$/)) {
#say "got a new state: $state";
$current_state = $state;
} else {
@@ -155,12 +155,20 @@ sub slurp {
# to generate a format string. The format uses %d for <number>s,
# literal numbers or state IDs and %s for NULL, <string>s and literal
# strings.
+
+ # remove the function name temporarily, so that the following
+ # replacements only apply to the arguments.
+ my ($funcname) = ($fmt =~ /^(.+)\(/);
+ $fmt =~ s/^$funcname//;
+
$fmt =~ s/$_/%d/g for @keys;
$fmt =~ s/\$([a-z_]+)/%s/g;
$fmt =~ s/\&([a-z_]+)/%ld/g;
$fmt =~ s/"([a-z0-9_]+)"/%s/g;
$fmt =~ s/(?:-?|\b)[0-9]+\b/%d/g;
+ $fmt = $funcname . $fmt;
+
say $callfh " case $call_id:";
say $callfh " result->next_state = $next_state;";
say $callfh '#ifndef TEST_PARSER';
@@ -51,6 +51,7 @@ CFGFUN(focus_follows_mouse, const char *value);
CFGFUN(mouse_warping, const char *value);
CFGFUN(force_focus_wrapping, const char *value);
CFGFUN(force_xinerama, const char *value);
+CFGFUN(disable_randr15, const char *value);
CFGFUN(fake_outputs, const char *outputs);
CFGFUN(force_display_urgency_hint, const long duration_ms);
CFGFUN(focus_on_window_activation, const char *mode);
View
@@ -156,6 +156,9 @@ struct Config {
* is fetched once and never updated. */
bool force_xinerama;
+ /** Don’t use RandR 1.5 for querying outputs. */
+ bool disable_randr15;
+
/** Overwrites output detection (for testing), see src/fake_outputs.c */
char *fake_outputs;
View
@@ -29,7 +29,7 @@ typedef enum {
* XRandR information to setup workspaces for each screen.
*
*/
-void randr_init(int *event_base);
+void randr_init(int *event_base, const bool disable_randr15);
/**
* Initializes a CT_OUTPUT Con (searches existing ones from inplace restart
View
@@ -37,6 +37,7 @@ state INITIAL:
'mouse_warping' -> MOUSE_WARPING
'force_focus_wrapping' -> FORCE_FOCUS_WRAPPING
'force_xinerama', 'force-xinerama' -> FORCE_XINERAMA
+ 'disable_randr15', 'disable-randr15' -> DISABLE_RANDR15
'workspace_auto_back_and_forth' -> WORKSPACE_BACK_AND_FORTH
'fake_outputs', 'fake-outputs' -> FAKE_OUTPUTS
'force_display_urgency_hint' -> FORCE_DISPLAY_URGENCY_HINT
@@ -205,6 +206,11 @@ state FORCE_XINERAMA:
value = word
-> call cfg_force_xinerama($value)
+# disable_randr15
+state DISABLE_RANDR15:
+ value = word
+ -> call cfg_disable_randr15($value)
+
# workspace_back_and_forth
state WORKSPACE_BACK_AND_FORTH:
value = word
View
@@ -252,6 +252,10 @@ CFGFUN(force_xinerama, const char *value) {
config.force_xinerama = eval_boolstr(value);
}
+CFGFUN(disable_randr15, const char *value) {
+ config.disable_randr15 = eval_boolstr(value);
+}
+
CFGFUN(force_focus_wrapping, const char *value) {
config.force_focus_wrapping = eval_boolstr(value);
}
View
@@ -1150,6 +1150,21 @@ static void handle_focus_in(xcb_focus_in_event_t *event) {
return;
}
+/*
+ * Handles ConfigureNotify events for the root window, which are generated when
+ * the monitor configuration changed.
+ *
+ */
+static void handle_configure_notify(xcb_configure_notify_event_t *event) {
+ if (event->event != root) {
+ DLOG("ConfigureNotify for non-root window 0x%08x, ignoring\n", event->event);
+ return;
+ }
+ DLOG("ConfigureNotify for root window 0x%08x\n", event->event);
+
+ randr_query_outputs();
+}
+
/*
* Handles the WM_CLASS property for assignments and criteria selection.
*
@@ -1476,6 +1491,10 @@ void handle_event(int type, xcb_generic_event_t *event) {
break;
}
+ case XCB_CONFIGURE_NOTIFY:
+ handle_configure_notify((xcb_configure_notify_event_t *)event);
+ break;
+
default:
//DLOG("Unhandled event of type %d\n", type);
break;
View
@@ -194,6 +194,7 @@ int main(int argc, char *argv[]) {
char *layout_path = NULL;
bool delete_layout_path = false;
bool force_xinerama = false;
+ bool disable_randr15 = false;
char *fake_outputs = NULL;
bool disable_signalhandler = false;
bool only_check_config = false;
@@ -209,6 +210,8 @@ int main(int argc, char *argv[]) {
{"restart", required_argument, 0, 0},
{"force-xinerama", no_argument, 0, 0},
{"force_xinerama", no_argument, 0, 0},
+ {"disable-randr15", no_argument, 0, 0},
+ {"disable_randr15", no_argument, 0, 0},
{"disable-signalhandler", no_argument, 0, 0},
{"shmlog-size", required_argument, 0, 0},
{"shmlog_size", required_argument, 0, 0},
@@ -289,6 +292,10 @@ int main(int argc, char *argv[]) {
"Please check if your driver really does not support RandR "
"and disable this option as soon as you can.\n");
break;
+ } else if (strcmp(long_options[option_index].name, "disable-randr15") == 0 ||
+ strcmp(long_options[option_index].name, "disable_randr15") == 0) {
+ disable_randr15 = true;
+ break;
} else if (strcmp(long_options[option_index].name, "disable-signalhandler") == 0) {
disable_signalhandler = true;
break;
@@ -661,7 +668,7 @@ int main(int argc, char *argv[]) {
xinerama_init();
} else {
DLOG("Checking for XRandR...\n");
- randr_init(&randr_base);
+ randr_init(&randr_base, disable_randr15 || config.disable_randr15);
}
/* We need to force disabling outputs which have been loaded from the
Oops, something went wrong.

0 comments on commit 633a9f7

Please sign in to comment.