commit 9e4a681b7d219520306a8c08f62cf6206a191b05
parent 735b48258cc770d6bbe9177deeaa064c200e6fa0
Author: Kebigon <git@kebigon.xyz>
Date: Thu, 12 Aug 2021 17:59:55 +0900
Handle XCB_RANDR_SCREEN_CHANGE_NOTIFY
Diffstat:
4 files changed, 41 insertions(+), 23 deletions(-)
diff --git a/events.c b/events.c
@@ -16,20 +16,25 @@
*/
#include "events.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <xcb/randr.h>
+
#include "client.h"
#include "kbgwm.h"
#include "list.h"
#include "log.h"
+#include "monitor.h"
#include "xcbutils.h"
-#include <assert.h>
-#include <stdio.h>
-
#define CLEANMASK(mask) (mask & ~(numlockmask | XCB_MOD_MASK_LOCK))
#define EVENT_HANDLERS_SIZE XCB_CONFIGURE_REQUEST + 1
static void (*event_handlers[EVENT_HANDLERS_SIZE])(xcb_generic_event_t *);
+extern int_least16_t randr_base;
+
static void handle_key_press(xcb_generic_event_t *e)
{
xcb_key_press_event_t *event = (xcb_key_press_event_t *)e;
@@ -256,6 +261,12 @@ static void handle_configure_request(xcb_generic_event_t *e)
void handle_event(xcb_generic_event_t *event)
{
+ if (randr_base > -1 && event->response_type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY)
+ {
+ monitors_refresh_config();
+ return;
+ }
+
void (*event_handler)(xcb_generic_event_t *) = event_handlers[event->response_type & ~0x80];
if (event_handler == NULL)
LOG_INFO_VA("Received unhandled event, response type %d", event->response_type & ~0x80);
diff --git a/kbgwm.c b/kbgwm.c
@@ -73,15 +73,19 @@ void mouseresize(__attribute__((unused)) const union Arg *arg)
void eventLoop()
{
+ xcb_generic_event_t *event;
+
while (running)
{
- xcb_generic_event_t *event = xcb_wait_for_event(c);
- log_debug_event(event);
+ if ((event = xcb_wait_for_event(c)) != NULL)
+ {
+ log_debug_event(event);
- handle_event(event);
+ handle_event(event);
- free(event);
- LOG_DEBUG("=======[ event: DONE ]=======\n");
+ free(event);
+ LOG_DEBUG("=======[ event: DONE ]=======\n");
+ }
}
}
diff --git a/monitor.c b/monitor.c
@@ -28,10 +28,9 @@ extern xcb_screen_t *screen;
extern const uint_least8_t workspaces_length;
extern struct item *workspaces[];
-uint8_t randr_base = -1;
+int_least16_t randr_base = -1;
struct item *monitors;
-void setup_randr_monitors(xcb_randr_get_screen_resources_current_reply_t *);
void monitor_add(xcb_randr_output_t, int16_t, int16_t, uint16_t, uint16_t);
struct item *monitor_find_by_id(const xcb_randr_output_t);
@@ -44,18 +43,7 @@ void setup_monitors()
return;
}
- const xcb_randr_get_screen_resources_current_cookie_t cookie =
- xcb_randr_get_screen_resources_current(c, screen->root);
- xcb_randr_get_screen_resources_current_reply_t *res =
- xcb_randr_get_screen_resources_current_reply(c, cookie, NULL);
- if (NULL == res)
- {
- LOG_WARN("Unable to retrieve the RANDR screen resources");
- return;
- }
-
- setup_randr_monitors(res);
- free(res);
+ monitors_refresh_config();
randr_base = extension->first_event;
xcb_randr_select_input(
@@ -119,8 +107,18 @@ void monitor_delete(struct item *mon_item)
}
}
-void setup_randr_monitors(xcb_randr_get_screen_resources_current_reply_t *res)
+void monitors_refresh_config()
{
+ const xcb_randr_get_screen_resources_current_cookie_t cookie =
+ xcb_randr_get_screen_resources_current(c, screen->root);
+ xcb_randr_get_screen_resources_current_reply_t *res =
+ xcb_randr_get_screen_resources_current_reply(c, cookie, NULL);
+ if (NULL == res)
+ {
+ LOG_WARN("Unable to retrieve the RANDR screen resources");
+ return;
+ }
+
int32_t len = xcb_randr_get_screen_resources_current_outputs_length(res);
xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(res);
@@ -150,6 +148,7 @@ void setup_randr_monitors(xcb_randr_get_screen_resources_current_reply_t *res)
// Already registered monitor -> delete it
if ((item = monitor_find_by_id(outputs[i])) != NULL)
{
+ monitor_delete(item);
}
continue;
@@ -176,6 +175,8 @@ void setup_randr_monitors(xcb_randr_get_screen_resources_current_reply_t *res)
free(crtc);
free(info);
}
+
+ free(res);
}
bool monitor_contains(struct monitor *monitor, uint16_t x, uint16_t y)
diff --git a/monitor.h b/monitor.h
@@ -38,3 +38,5 @@ bool monitor_contains(struct monitor *, uint16_t, uint16_t);
* Find a monitor from a position
*/
struct item *monitor_find_by_position(const uint16_t, const uint16_t);
+
+void monitors_refresh_config();