Correctly set globalconf.primary_screen under RandR

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-02-27 15:57:57 +01:00
parent 110893d9cb
commit 2027dd8b02
4 changed files with 66 additions and 2 deletions

View File

@ -827,6 +827,9 @@ event_handle_randr_output_change_notify(xcb_randr_notify_event_t *ev)
p_delete(&output_name); p_delete(&output_name);
p_delete(&info); p_delete(&info);
/* The docs for RRSetOutputPrimary say we get this signal */
screen_update_primary();
} }
} }

View File

@ -82,6 +82,8 @@ typedef struct
screen_array_t screens; screen_array_t screens;
/** The primary screen, access through screen_get_primary() */ /** The primary screen, access through screen_get_primary() */
screen_t *primary_screen; screen_t *primary_screen;
/** Do we have RandR 1.3 or newer? */
bool have_randr_13;
/** Root window key bindings */ /** Root window key bindings */
key_array_t keys; key_array_t keys;
/** Root window mouse bindings */ /** Root window mouse bindings */

View File

@ -61,6 +61,8 @@ struct screen_output_t
char *name; char *name;
/** The size in millimeters */ /** The size in millimeters */
uint32_t mm_width, mm_height; uint32_t mm_width, mm_height;
/** The XID */
xcb_randr_output_t output;
}; };
static void static void
@ -151,11 +153,20 @@ screen_scan_randr(void)
{ {
xcb_randr_query_version_reply_t *version_reply = xcb_randr_query_version_reply_t *version_reply =
xcb_randr_query_version_reply(globalconf.connection, xcb_randr_query_version_reply(globalconf.connection,
xcb_randr_query_version(globalconf.connection, 1, 1), 0); xcb_randr_query_version(globalconf.connection, 1, 3), 0);
if(version_reply) if(version_reply)
{ {
uint32_t major_version = version_reply->major_version;
uint32_t minor_version = version_reply->minor_version;
p_delete(&version_reply); p_delete(&version_reply);
/* Do we agree on a supported version? */
if (major_version != 1 || minor_version < 2)
return false;
globalconf.have_randr_13 = minor_version >= 3;
/* A quick XRandR recall: /* A quick XRandR recall:
* You have CRTC that manages a part of a SCREEN. * You have CRTC that manages a part of a SCREEN.
* Each CRTC can draw stuff on one or more OUTPUT. */ * Each CRTC can draw stuff on one or more OUTPUT. */
@ -207,7 +218,8 @@ screen_scan_randr(void)
screen_output_array_append(&new_screen->outputs, screen_output_array_append(&new_screen->outputs,
(screen_output_t) { .name = name, (screen_output_t) { .name = name,
.mm_width = output_info_r->mm_width, .mm_width = output_info_r->mm_width,
.mm_height = output_info_r->mm_height }); .mm_height = output_info_r->mm_height,
.output = randr_outputs[j] });
p_delete(&output_info_r); p_delete(&output_info_r);
} }
@ -218,6 +230,7 @@ screen_scan_randr(void)
} }
p_delete(&screen_res_r); p_delete(&screen_res_r);
screen_update_primary();
return screens_exist(); return screens_exist();
} }
@ -537,6 +550,47 @@ screen_get_index(screen_t *s)
return 0; return 0;
} }
void
screen_update_primary(void)
{
if (!globalconf.have_randr_13)
return;
screen_t *primary_screen = NULL;
xcb_randr_get_output_primary_reply_t *primary =
xcb_randr_get_output_primary_reply(globalconf.connection,
xcb_randr_get_output_primary(globalconf.connection, globalconf.screen->root),
NULL);
if (!primary)
return;
foreach(screen, globalconf.screens)
{
foreach(output, (*screen)->outputs)
if (output->output == primary->output)
primary_screen = *screen;
}
p_delete(&primary);
if (!primary_screen || primary_screen == globalconf.primary_screen)
return;
lua_State *L = globalconf_get_lua_State();
screen_t *old = globalconf.primary_screen;
globalconf.primary_screen = primary_screen;
if (old)
{
luaA_object_push(L, old);
luaA_object_emit_signal(L, -1, "primary_changed", 0);
lua_pop(L, 1);
}
luaA_object_push(L, primary_screen);
luaA_object_emit_signal(L, -1, "primary_changed", 0);
lua_pop(L, 1);
}
screen_t * screen_t *
screen_get_primary(void) screen_get_primary(void)
{ {
@ -662,6 +716,10 @@ screen_class_setup(lua_State *L)
* @signal property::workarea * @signal property::workarea
*/ */
signal_add(&screen_class.signals, "property::workarea"); signal_add(&screen_class.signals, "property::workarea");
/**
* @signal primary_changed
*/
signal_add(&screen_class.signals, "primary_changed");
} }
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -47,6 +47,7 @@ bool screen_coord_in_screen(screen_t *, int, int);
int screen_get_index(screen_t *); int screen_get_index(screen_t *);
area_t display_area_get(void); area_t display_area_get(void);
void screen_client_moveto(client_t *, screen_t *, bool); void screen_client_moveto(client_t *, screen_t *, bool);
void screen_update_primary(void);
screen_t *screen_get_primary(void); screen_t *screen_get_primary(void);
void luaA_pushscreen(lua_State *, screen_t *); void luaA_pushscreen(lua_State *, screen_t *);