Stop restarting on RandR changes
This commit adds a "removed" signal to screens. Together with the "added" signal that we have since a while, this allows the C code to update the list of available screens dynamically without needing to restart. So far, this code received only minimal testing. So far, I don't have a nice idea on how to easily test this... Closes: https://github.com/awesomeWM/awesome/issues/672 Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
8de8df1415
commit
b651373cda
5
event.c
5
event.c
|
@ -400,8 +400,7 @@ event_handle_configurenotify(xcb_configure_notify_event_t *ev)
|
||||||
xcb_screen_t *screen = globalconf.screen;
|
xcb_screen_t *screen = globalconf.screen;
|
||||||
|
|
||||||
if(ev->window == screen->root)
|
if(ev->window == screen->root)
|
||||||
/* it's not that we panic, but restart */
|
globalconf.screen_need_refresh = true;
|
||||||
awesome_restart();
|
|
||||||
|
|
||||||
/* Copy what XRRUpdateConfiguration() would do: Update the configuration */
|
/* Copy what XRRUpdateConfiguration() would do: Update the configuration */
|
||||||
if(ev->window == screen->root) {
|
if(ev->window == screen->root) {
|
||||||
|
@ -782,7 +781,7 @@ event_handle_randr_screen_change_notify(xcb_randr_screen_change_notify_event_t *
|
||||||
globalconf.screen->height_in_pixels = ev->height;
|
globalconf.screen->height_in_pixels = ev->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
awesome_restart();
|
globalconf.screen_need_refresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** XRandR event handler for RRNotify subtype XRROutputChangeNotifyEvent
|
/** XRandR event handler for RRNotify subtype XRROutputChangeNotifyEvent
|
||||||
|
|
4
event.h
4
event.h
|
@ -38,9 +38,13 @@ void drawin_refresh(void);
|
||||||
void client_focus_refresh(void);
|
void client_focus_refresh(void);
|
||||||
void client_border_refresh(void);
|
void client_border_refresh(void);
|
||||||
|
|
||||||
|
/* objects/screen.c */
|
||||||
|
void screen_refresh(void);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
awesome_refresh(void)
|
awesome_refresh(void)
|
||||||
{
|
{
|
||||||
|
screen_refresh();
|
||||||
luaA_emit_refresh();
|
luaA_emit_refresh();
|
||||||
banning_refresh();
|
banning_refresh();
|
||||||
stack_refresh();
|
stack_refresh();
|
||||||
|
|
|
@ -92,6 +92,10 @@ typedef struct
|
||||||
xcb_window_t selection_owner_window;
|
xcb_window_t selection_owner_window;
|
||||||
/** Do we have RandR 1.3 or newer? */
|
/** Do we have RandR 1.3 or newer? */
|
||||||
bool have_randr_13;
|
bool have_randr_13;
|
||||||
|
/** Do we have RandR 1.5 or newer? */
|
||||||
|
bool have_randr_15;
|
||||||
|
/** Do we have a RandR screen update pending? */
|
||||||
|
bool screen_need_refresh;
|
||||||
/** Check for XTest extension */
|
/** Check for XTest extension */
|
||||||
bool have_xtest;
|
bool have_xtest;
|
||||||
/** Check for SHAPE extension */
|
/** Check for SHAPE extension */
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "banning.h"
|
#include "banning.h"
|
||||||
#include "objects/client.h"
|
#include "objects/client.h"
|
||||||
#include "objects/drawin.h"
|
#include "objects/drawin.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -233,6 +234,7 @@ screen_scan_randr_monitors(lua_State *L, screen_array_t *screens)
|
||||||
new_screen->geometry.y = monitor_iter.data->y;
|
new_screen->geometry.y = monitor_iter.data->y;
|
||||||
new_screen->geometry.width = monitor_iter.data->width;
|
new_screen->geometry.width = monitor_iter.data->width;
|
||||||
new_screen->geometry.height = monitor_iter.data->height;
|
new_screen->geometry.height = monitor_iter.data->height;
|
||||||
|
new_screen->xid = monitor_iter.data->name;
|
||||||
|
|
||||||
output.mm_width = monitor_iter.data->width_in_millimeters;
|
output.mm_width = monitor_iter.data->width_in_millimeters;
|
||||||
output.mm_height = monitor_iter.data->height_in_millimeters;
|
output.mm_height = monitor_iter.data->height_in_millimeters;
|
||||||
|
@ -296,6 +298,7 @@ screen_scan_randr_crtcs(lua_State *L, screen_array_t *screens)
|
||||||
new_screen->geometry.y = crtc_info_r->y;
|
new_screen->geometry.y = crtc_info_r->y;
|
||||||
new_screen->geometry.width= crtc_info_r->width;
|
new_screen->geometry.width= crtc_info_r->width;
|
||||||
new_screen->geometry.height= crtc_info_r->height;
|
new_screen->geometry.height= crtc_info_r->height;
|
||||||
|
new_screen->xid = randr_crtcs[i];
|
||||||
|
|
||||||
xcb_randr_output_t *randr_outputs = xcb_randr_get_crtc_info_outputs(crtc_info_r);
|
xcb_randr_output_t *randr_outputs = xcb_randr_get_crtc_info_outputs(crtc_info_r);
|
||||||
|
|
||||||
|
@ -370,13 +373,18 @@ screen_scan_randr(lua_State *L, screen_array_t *screens)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
globalconf.have_randr_13 = minor_version >= 3;
|
globalconf.have_randr_13 = minor_version >= 3;
|
||||||
|
#if XCB_RANDR_MAJOR_VERSION > 1 || XCB_RANDR_MINOR_VERSION >= 5
|
||||||
|
globalconf.have_randr_15 = minor_version >= 5;
|
||||||
|
#else
|
||||||
|
globalconf.have_randr_15 = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We want to know when something changes */
|
/* We want to know when something changes */
|
||||||
xcb_randr_select_input(globalconf.connection,
|
xcb_randr_select_input(globalconf.connection,
|
||||||
globalconf.screen->root,
|
globalconf.screen->root,
|
||||||
XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE);
|
XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE);
|
||||||
|
|
||||||
if (minor_version >= 5)
|
if (globalconf.have_randr_15)
|
||||||
screen_scan_randr_monitors(L, screens);
|
screen_scan_randr_monitors(L, screens);
|
||||||
else
|
else
|
||||||
screen_scan_randr_crtcs(L, screens);
|
screen_scan_randr_crtcs(L, screens);
|
||||||
|
@ -455,6 +463,61 @@ screen_scan(void)
|
||||||
screen_update_primary();
|
screen_update_primary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_refresh(void)
|
||||||
|
{
|
||||||
|
if(!globalconf.screen_need_refresh)
|
||||||
|
return;
|
||||||
|
globalconf.screen_need_refresh = false;
|
||||||
|
|
||||||
|
screen_array_t new_screens;
|
||||||
|
lua_State *L = globalconf_get_lua_State();
|
||||||
|
|
||||||
|
screen_array_init(&new_screens);
|
||||||
|
if (globalconf.have_randr_15)
|
||||||
|
screen_scan_randr_monitors(L, &new_screens);
|
||||||
|
else
|
||||||
|
screen_scan_randr_crtcs(L, &new_screens);
|
||||||
|
|
||||||
|
/* Add new screens */
|
||||||
|
foreach(new_screen, new_screens) {
|
||||||
|
bool found = false;
|
||||||
|
foreach(old_screen, globalconf.screens)
|
||||||
|
found |= (*new_screen)->xid == (*old_screen)->xid;
|
||||||
|
if(!found) {
|
||||||
|
screen_array_append(&globalconf.screens, *new_screen);
|
||||||
|
luaA_object_push(L, *new_screen);
|
||||||
|
luaA_object_emit_signal(L, -1, "added", 0);
|
||||||
|
/* Get an extra reference since both new_screens and
|
||||||
|
* globalconf.screens reference this screen now */
|
||||||
|
luaA_object_ref(L, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove screens which are gone */
|
||||||
|
for(int i = 0; i < globalconf.screens.len; i++) {
|
||||||
|
screen_t *old_screen = globalconf.screens.tab[i];
|
||||||
|
bool found = false;
|
||||||
|
foreach(new_screen, new_screens)
|
||||||
|
found |= (*new_screen)->xid == old_screen->xid;
|
||||||
|
if(!found) {
|
||||||
|
luaA_object_push(L, old_screen);
|
||||||
|
luaA_object_emit_signal(L, -1, "removed", 0);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
screen_array_take(&globalconf.screens, i);
|
||||||
|
luaA_object_unref(L, old_screen);
|
||||||
|
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(screen, new_screens)
|
||||||
|
luaA_object_unref(L, *screen);
|
||||||
|
screen_array_wipe(&new_screens);
|
||||||
|
|
||||||
|
screen_update_primary();
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the squared distance of the given screen to the coordinates.
|
/** Return the squared distance of the given screen to the coordinates.
|
||||||
* \param screen The screen
|
* \param screen The screen
|
||||||
* \param x X coordinate
|
* \param x X coordinate
|
||||||
|
@ -900,6 +963,11 @@ screen_class_setup(lua_State *L)
|
||||||
* @signal .added
|
* @signal .added
|
||||||
*/
|
*/
|
||||||
signal_add(&screen_class.signals, "added");
|
signal_add(&screen_class.signals, "added");
|
||||||
|
/**
|
||||||
|
* This signal is emitted when a screen is removed from the setup.
|
||||||
|
* @signal removed
|
||||||
|
*/
|
||||||
|
signal_add(&screen_class.signals, "removed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||||
|
|
|
@ -37,6 +37,8 @@ struct a_screen
|
||||||
area_t geometry;
|
area_t geometry;
|
||||||
/** The screen outputs informations */
|
/** The screen outputs informations */
|
||||||
screen_output_array_t outputs;
|
screen_output_array_t outputs;
|
||||||
|
/** Some XID identifying this screen */
|
||||||
|
uint32_t xid;
|
||||||
};
|
};
|
||||||
ARRAY_FUNCS(screen_t *, screen, DO_NOTHING)
|
ARRAY_FUNCS(screen_t *, screen, DO_NOTHING)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue