From 110893d9cbc001759033bd0803cfb3174a0ce55c Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 27 Feb 2016 15:44:25 +0100 Subject: [PATCH 1/3] Add screen.primary Right now this just always returns the first screens, but this can easily be implemented properly later. Signed-off-by: Uli Schlachter --- globalconf.h | 2 ++ mouse.c | 2 +- objects/screen.c | 14 ++++++++++++++ objects/screen.h | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/globalconf.h b/globalconf.h index f936369e3..4d44d9d96 100644 --- a/globalconf.h +++ b/globalconf.h @@ -80,6 +80,8 @@ typedef struct xcb_key_symbols_t *keysyms; /** Logical screens */ screen_array_t screens; + /** The primary screen, access through screen_get_primary() */ + screen_t *primary_screen; /** Root window key bindings */ key_array_t keys; /** Root window mouse bindings */ diff --git a/mouse.c b/mouse.c index af080b286..cf7bf4989 100644 --- a/mouse.c +++ b/mouse.c @@ -135,7 +135,7 @@ luaA_mouse_index(lua_State *L) if (globalconf.focus.client) luaA_pushscreen(L, globalconf.focus.client->screen); else - luaA_pushscreen(L, globalconf.screens.tab[0]); + luaA_pushscreen(L, screen_get_primary()); return 1; } diff --git a/objects/screen.c b/objects/screen.c index 3026c827c..d0cecc527 100644 --- a/objects/screen.c +++ b/objects/screen.c @@ -44,6 +44,7 @@ /** Screen is a table where indexes are screen numbers. You can use `screen[1]` * to get access to the first screen, etc. Alternatively, if RANDR information * is available, you can use output names for finding screen objects. + * The primary screen can be accessed as `screen.primary`. * Each screen has a set of properties. * * @tfield table geometry The screen coordinates. Immutable. @@ -536,6 +537,14 @@ screen_get_index(screen_t *s) return 0; } +screen_t * +screen_get_primary(void) +{ + if (!globalconf.primary_screen && globalconf.screens.len > 0) + globalconf.primary_screen = globalconf.screens.tab[0]; + return globalconf.primary_screen; +} + /** Screen module. * \param L The Lua VM state. * \return The number of elements pushed on stack. @@ -548,10 +557,15 @@ luaA_screen_module_index(lua_State *L) const char *name; if(lua_type(L, 2) == LUA_TSTRING && (name = lua_tostring(L, 2))) + { + if(A_STREQ(name, "primary")) + return luaA_object_push(L, screen_get_primary()); + foreach(screen, globalconf.screens) foreach(output, (*screen)->outputs) if(A_STREQ(output->name, name)) return luaA_object_push(L, screen); + } return luaA_object_push(L, luaA_checkscreen(L, 2)); } diff --git a/objects/screen.h b/objects/screen.h index 95cf5d821..9cad113c4 100644 --- a/objects/screen.h +++ b/objects/screen.h @@ -47,6 +47,7 @@ bool screen_coord_in_screen(screen_t *, int, int); int screen_get_index(screen_t *); area_t display_area_get(void); void screen_client_moveto(client_t *, screen_t *, bool); +screen_t *screen_get_primary(void); void luaA_pushscreen(lua_State *, screen_t *); screen_t *luaA_checkscreen(lua_State *, int); From 2027dd8b02b57834c525ea6cfc6058d1a3e8a445 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 27 Feb 2016 15:57:57 +0100 Subject: [PATCH 2/3] Correctly set globalconf.primary_screen under RandR Signed-off-by: Uli Schlachter --- event.c | 3 +++ globalconf.h | 2 ++ objects/screen.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- objects/screen.h | 1 + 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/event.c b/event.c index f52723330..ee121362d 100644 --- a/event.c +++ b/event.c @@ -827,6 +827,9 @@ event_handle_randr_output_change_notify(xcb_randr_notify_event_t *ev) p_delete(&output_name); p_delete(&info); + + /* The docs for RRSetOutputPrimary say we get this signal */ + screen_update_primary(); } } diff --git a/globalconf.h b/globalconf.h index 4d44d9d96..8d5791cc6 100644 --- a/globalconf.h +++ b/globalconf.h @@ -82,6 +82,8 @@ typedef struct screen_array_t screens; /** The primary screen, access through screen_get_primary() */ screen_t *primary_screen; + /** Do we have RandR 1.3 or newer? */ + bool have_randr_13; /** Root window key bindings */ key_array_t keys; /** Root window mouse bindings */ diff --git a/objects/screen.c b/objects/screen.c index d0cecc527..a18d9646c 100644 --- a/objects/screen.c +++ b/objects/screen.c @@ -61,6 +61,8 @@ struct screen_output_t char *name; /** The size in millimeters */ uint32_t mm_width, mm_height; + /** The XID */ + xcb_randr_output_t output; }; static void @@ -151,11 +153,20 @@ screen_scan_randr(void) { xcb_randr_query_version_reply_t *version_reply = 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) { + uint32_t major_version = version_reply->major_version; + uint32_t minor_version = version_reply->minor_version; + 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: * You have CRTC that manages a part of a SCREEN. * 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_t) { .name = name, .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); } @@ -218,6 +230,7 @@ screen_scan_randr(void) } p_delete(&screen_res_r); + screen_update_primary(); return screens_exist(); } @@ -537,6 +550,47 @@ screen_get_index(screen_t *s) 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_get_primary(void) { @@ -662,6 +716,10 @@ screen_class_setup(lua_State *L) * @signal 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 diff --git a/objects/screen.h b/objects/screen.h index 9cad113c4..28ecf6b20 100644 --- a/objects/screen.h +++ b/objects/screen.h @@ -47,6 +47,7 @@ bool screen_coord_in_screen(screen_t *, int, int); int screen_get_index(screen_t *); area_t display_area_get(void); void screen_client_moveto(client_t *, screen_t *, bool); +void screen_update_primary(void); screen_t *screen_get_primary(void); void luaA_pushscreen(lua_State *, screen_t *); From b02b2f79569f1a155ff04a81a087804a5779b860 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 27 Feb 2016 16:45:43 +0100 Subject: [PATCH 3/3] Fix screen index by output name Signed-off-by: Uli Schlachter --- objects/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/objects/screen.c b/objects/screen.c index a18d9646c..924b30596 100644 --- a/objects/screen.c +++ b/objects/screen.c @@ -618,7 +618,7 @@ luaA_screen_module_index(lua_State *L) foreach(screen, globalconf.screens) foreach(output, (*screen)->outputs) if(A_STREQ(output->name, name)) - return luaA_object_push(L, screen); + return luaA_object_push(L, *screen); } return luaA_object_push(L, luaA_checkscreen(L, 2));