]> git.lizzy.rs Git - bspwm.git/commitdiff
Postpone events on windows of pending rules
authorBastien Dejean <nihilhill@gmail.com>
Sun, 22 Jul 2018 19:08:59 +0000 (21:08 +0200)
committerBastien Dejean <nihilhill@gmail.com>
Sun, 22 Jul 2018 19:08:59 +0000 (21:08 +0200)
Fixes #822.

src/bspwm.c
src/events.c
src/rule.c
src/rule.h
src/types.h
src/window.c
src/window.h

index 41735e88313f2c1aaf9dd4c2dbc710166a0963c1..e938b538bc1b824a72cd9f7c26bef537d2268c4c 100644 (file)
@@ -155,7 +155,11 @@ int main(int argc, char *argv[])
                        while (pr != NULL) {
                                pending_rule_t *next = pr->next;
                                if (FD_ISSET(pr->fd, &descriptors)) {
-                                       manage_window(pr->win, pr->csq, pr->fd);
+                                       if (manage_window(pr->win, pr->csq, pr->fd)) {
+                                               for (event_queue_t *eq = pr->event_head; eq != NULL; eq = eq->next) {
+                                                       handle_event(&eq->event);
+                                               }
+                                       }
                                        remove_pending_rule(pr);
                                }
                                pr = next;
index 4de3fa6f4e95b994359bc38ad66a946f0364bab6..dc069632b15166ce8c1f89e5e2f2fca6ff898fb3 100644 (file)
@@ -32,6 +32,7 @@
 #include "tree.h"
 #include "window.h"
 #include "pointer.h"
+#include "rule.h"
 #include "events.h"
 
 void handle_event(xcb_generic_event_t *evt)
@@ -273,7 +274,13 @@ void property_notify(xcb_generic_event_t *evt)
 
        coordinates_t loc;
        if (!locate_window(e->window, &loc)) {
-                       return;
+               for (pending_rule_t *pr = pending_rule_head; pr != NULL; pr = pr->next) {
+                       if (pr->win == e->window) {
+                               postpone_event(pr, evt);
+                               break;
+                       }
+               }
+               return;
        }
 
        if (e->atom == XCB_ATOM_WM_HINTS) {
@@ -303,6 +310,12 @@ void client_message(xcb_generic_event_t *evt)
 
        coordinates_t loc;
        if (!locate_window(e->window, &loc)) {
+               for (pending_rule_t *pr = pending_rule_head; pr != NULL; pr = pr->next) {
+                       if (pr->win == e->window) {
+                               postpone_event(pr, evt);
+                               break;
+                       }
+               }
                return;
        }
 
index e4b11716c344f4dedd58f48bdbe86e66872a368d..2dc4a5ddfce6d326d832a33987790aecf87e06ed 100644 (file)
@@ -118,6 +118,7 @@ pending_rule_t *make_pending_rule(int fd, xcb_window_t win, rule_consequence_t *
 {
        pending_rule_t *pr = calloc(1, sizeof(pending_rule_t));
        pr->prev = pr->next = NULL;
+       pr->event_head = pr->event_tail = NULL;
        pr->fd = fd;
        pr->win = win;
        pr->csq = csq;
@@ -159,9 +160,36 @@ void remove_pending_rule(pending_rule_t *pr)
        }
        close(pr->fd);
        free(pr->csq);
+       event_queue_t *eq = pr->event_head;
+       while (eq != NULL) {
+               event_queue_t *next = eq->next;
+               free(eq);
+               eq = next;
+       }
        free(pr);
 }
 
+void postpone_event(pending_rule_t *pr, xcb_generic_event_t *evt)
+{
+       event_queue_t *eq = make_event_queue(evt);
+       if (pr->event_tail == NULL) {
+               pr->event_head = pr->event_tail = eq;
+       } else {
+               pr->event_tail->next = eq;
+               eq->prev = pr->event_tail;
+               pr->event_tail = eq;
+       }
+}
+
+event_queue_t *make_event_queue(xcb_generic_event_t *evt)
+{
+       event_queue_t *eq = calloc(1, sizeof(event_queue_t));
+       eq->prev = eq->next = NULL;
+       eq->event = *evt;
+       return eq;
+}
+
+
 #define SET_CSQ_STATE(val) \
        do { \
                if (csq->state == NULL) { \
@@ -178,7 +206,7 @@ void remove_pending_rule(pending_rule_t *pr)
                *(csq->layer) = (val); \
        } while (0)
 
-static void _apply_window_type(xcb_window_t win, rule_consequence_t *csq)
+void _apply_window_type(xcb_window_t win, rule_consequence_t *csq)
 {
        xcb_ewmh_get_atoms_reply_t win_type;
        if (xcb_ewmh_get_wm_window_type_reply(ewmh, xcb_ewmh_get_wm_window_type(ewmh, win), &win_type, NULL) == 1) {
@@ -203,7 +231,7 @@ static void _apply_window_type(xcb_window_t win, rule_consequence_t *csq)
        }
 }
 
-static void _apply_window_state(xcb_window_t win, rule_consequence_t *csq)
+void _apply_window_state(xcb_window_t win, rule_consequence_t *csq)
 {
        xcb_ewmh_get_atoms_reply_t win_state;
        if (xcb_ewmh_get_wm_state_reply(ewmh, xcb_ewmh_get_wm_state(ewmh, win), &win_state, NULL) == 1) {
@@ -223,7 +251,7 @@ static void _apply_window_state(xcb_window_t win, rule_consequence_t *csq)
        }
 }
 
-static void _apply_transient(xcb_window_t win, rule_consequence_t *csq)
+void _apply_transient(xcb_window_t win, rule_consequence_t *csq)
 {
        xcb_window_t transient_for = XCB_NONE;
        xcb_icccm_get_wm_transient_for_reply(dpy, xcb_icccm_get_wm_transient_for(dpy, win), &transient_for, NULL);
@@ -232,7 +260,7 @@ static void _apply_transient(xcb_window_t win, rule_consequence_t *csq)
        }
 }
 
-static void _apply_hints(xcb_window_t win, rule_consequence_t *csq)
+void _apply_hints(xcb_window_t win, rule_consequence_t *csq)
 {
        xcb_size_hints_t size_hints;
        if (xcb_icccm_get_wm_normal_hints_reply(dpy, xcb_icccm_get_wm_normal_hints(dpy, win), &size_hints, NULL) == 1) {
@@ -243,7 +271,7 @@ static void _apply_hints(xcb_window_t win, rule_consequence_t *csq)
        }
 }
 
-static void _apply_class(xcb_window_t win, rule_consequence_t *csq)
+void _apply_class(xcb_window_t win, rule_consequence_t *csq)
 {
        xcb_icccm_get_wm_class_reply_t reply;
        if (xcb_icccm_get_wm_class_reply(dpy, xcb_icccm_get_wm_class(dpy, win), &reply, NULL) == 1) {
index b9ac1629ed1c1bbf5be2ff4dff47b8275ce149a6..89f559cb2f87886da6c7324d96538dd488df5e1b 100644 (file)
@@ -37,10 +37,17 @@ rule_consequence_t *make_rule_conquence(void);
 pending_rule_t *make_pending_rule(int fd, xcb_window_t win, rule_consequence_t *csq);
 void add_pending_rule(pending_rule_t *pr);
 void remove_pending_rule(pending_rule_t *pr);
+void postpone_event(pending_rule_t *pr, xcb_generic_event_t *evt);
+event_queue_t *make_event_queue(xcb_generic_event_t *evt);
+void _apply_window_type(xcb_window_t win, rule_consequence_t *csq);
+void _apply_window_state(xcb_window_t win, rule_consequence_t *csq);
+void _apply_transient(xcb_window_t win, rule_consequence_t *csq);
+void _apply_hints(xcb_window_t win, rule_consequence_t *csq);
+void _apply_class(xcb_window_t win, rule_consequence_t *csq);
+void parse_keys_values(char *buf, rule_consequence_t *csq);
 void apply_rules(xcb_window_t win, rule_consequence_t *csq);
 bool schedule_rules(xcb_window_t win, rule_consequence_t *csq);
 void parse_rule_consequence(int fd, rule_consequence_t *csq);
-void parse_keys_values(char *buf, rule_consequence_t *csq);
 void parse_key_value(char *key, char *value, rule_consequence_t *csq);
 void list_rules(FILE *rsp);
 
index 4f936b5438c26b368a767db066a86ebd6b50bcbf..fb8952d517528eccea70e3a7246f8fd02b5fdfe9 100644 (file)
@@ -311,6 +311,13 @@ struct stacking_list_t {
        stacking_list_t *next;
 };
 
+typedef struct event_queue_t event_queue_t;
+struct event_queue_t {
+       xcb_generic_event_t event;
+       event_queue_t *prev;
+       event_queue_t *next;
+};
+
 typedef struct subscriber_list_t subscriber_list_t;
 struct subscriber_list_t {
        int fd;
@@ -360,6 +367,8 @@ struct pending_rule_t {
        int fd;
        xcb_window_t win;
        rule_consequence_t *csq;
+       event_queue_t *event_head;
+       event_queue_t *event_tail;
        pending_rule_t *prev;
        pending_rule_t *next;
 };
index 7cfcd6ef807d1d74f5e322ef76de5fbb4109c4ea..56f41ee05054b587caf71aa8dd2b443515b0dc69 100644 (file)
@@ -69,7 +69,7 @@ void schedule_window(xcb_window_t win)
        }
 }
 
-void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
+bool manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
 {
        monitor_t *m = mon;
        desktop_t *d = mon->desk;
@@ -87,7 +87,7 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
                free(csq->layer);
                free(csq->state);
                window_show(win);
-               return;
+               return false;
        }
 
        if (csq->node_desc[0] != '\0') {
@@ -209,6 +209,8 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
        ewmh_update_client_list(false);
        free(csq->layer);
        free(csq->state);
+
+       return true;
 }
 
 void set_window_state(xcb_window_t win, xcb_icccm_wm_state_t state)
index 7b5376ef1265aca1953d639441b963de7659b0ed..414ebea0100a343d2e8911453ed69b420df49fb4 100644 (file)
@@ -32,7 +32,7 @@
 #include "types.h"
 
 void schedule_window(xcb_window_t win);
-void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd);
+bool manage_window(xcb_window_t win, rule_consequence_t *csq, int fd);
 void set_window_state(xcb_window_t win, xcb_icccm_wm_state_t state);
 void unmanage_window(xcb_window_t win);
 bool is_presel_window(xcb_window_t win);