diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-05 19:22:34 +0000 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-21 14:02:56 +0000 |
commit | f3d5b07eb239e1d0206bbfaafeb6873aa044bf12 (patch) | |
tree | b0f3143732345199d2fd2606cf9842c29c9bb1fe | |
parent | 0cfdc429539986a841036dbfcd87f825f52e0a87 (diff) |
First pass at a general mechanism for signaling XCWM_ events when a property of interest changes
-rw-r--r-- | include/xcwm/event.h | 3 | ||||
-rw-r--r-- | src/libxcwm/atoms.c | 86 | ||||
-rw-r--r-- | src/libxcwm/event_loop.c | 19 | ||||
-rw-r--r-- | src/libxcwm/xcwm_internal.h | 19 |
4 files changed, 92 insertions, 35 deletions
diff --git a/include/xcwm/event.h b/include/xcwm/event.h index 94ea622..b146037 100644 --- a/include/xcwm/event.h +++ b/include/xcwm/event.h @@ -42,7 +42,8 @@ typedef enum xcwm_event_type_t { XCWM_EVENT_WINDOW_EXPOSE, XCWM_EVENT_WINDOW_CREATE, XCWM_EVENT_WINDOW_DESTROY, - XCWM_EVENT_WINDOW_NAME + XCWM_EVENT_WINDOW_NAME, + XCWM_EVENT_WINDOW_APPEARANCE, } xcwm_event_type_t; /** diff --git a/src/libxcwm/atoms.c b/src/libxcwm/atoms.c index ad1e7b8..7a98ea6 100644 --- a/src/libxcwm/atoms.c +++ b/src/libxcwm/atoms.c @@ -46,17 +46,48 @@ check_wm_cm_owner(xcwm_context_t *context); void create_wm_cm_window(xcwm_context_t *context); +/* + The table of xcwm_property_t represents the window properties we take note of, + the function to update our internal state on a change of that property, and + the event we send when that state changes. + */ +typedef struct xcwm_property_t xcwm_property_t; + +typedef void (xcwm_property_change_fn_t)(xcwm_window_t *window, xcwm_property_t *property); + +struct xcwm_property_t +{ + const char *name; + xcwm_property_change_fn_t *prop_change_fn; + xcwm_event_type_t event; + xcb_atom_t atom; +}; + /* Determine the window type */ static void -setup_window_type(xcwm_window_t *window); +setup_window_type(xcwm_window_t *window, xcwm_property_t *property); /* Get and set the size hints for the window */ static void -set_window_size_hints(xcwm_window_t *window); +set_window_size_hints(xcwm_window_t *window, xcwm_property_t *property); /* Get opacity hint */ static void -set_window_opacity(xcwm_window_t *window); +set_window_opacity(xcwm_window_t *window, xcwm_property_t *property); + +/* Get window name */ +static void +set_window_name(xcwm_window_t *window, xcwm_property_t *property); + +xcwm_property_t property_table[] = + { + { "_NET_WM_NAME", set_window_name, XCWM_EVENT_WINDOW_NAME }, + { "WM_NAME", set_window_name, XCWM_EVENT_WINDOW_NAME }, + { "_NET_WM_WINDOW_TYPE", setup_window_type, XCWM_EVENT_WINDOW_APPEARANCE }, + { "WM_NORMAL_HINTS", set_window_size_hints, 0 }, + { "_NET_WM_WINDOW_OPACITY", set_window_opacity, XCWM_EVENT_WINDOW_APPEARANCE }, + { NULL, NULL, 0 } + }; static xcb_atom_t _xcwm_atom_get(xcwm_context_t *context, const char *atomName) @@ -130,13 +161,15 @@ _xcwm_atoms_init(xcwm_context_t *context) /* Get the ICCCM atoms we need that are not included in the * xcb_ewmh_connection_t. */ + int i; + for (i = 0; property_table[i].name != NULL; i++) + { + property_table[i].atom = _xcwm_atom_get(context, property_table[i].name); + } /* WM_DELETE_WINDOW atom */ context->atoms->wm_delete_window_atom = _xcwm_atom_get(context, "WM_DELETE_WINDOW"); - /* WM_NAME */ - context->atoms->wm_name_atom = _xcwm_atom_get(context, "WM_NAME"); - if (!check_wm_cm_owner(context)) { return XCB_WINDOW; } @@ -145,9 +178,6 @@ _xcwm_atoms_init(xcwm_context_t *context) /* WM_STATE atom */ context->atoms->wm_state_atom = _xcwm_atom_get(context, "WM_STATE"); - /* NET_WM_OPACITY */ - context->atoms->wm_opacity_atom = _xcwm_atom_get(context, "_NET_WM_WINDOW_OPACITY"); - return 0; } @@ -200,16 +230,36 @@ create_wm_cm_window(xcwm_context_t *context) void _xcwm_atoms_init_window(xcwm_window_t *window) { - _xcwm_atoms_set_window_name(window); _xcwm_atoms_set_wm_delete(window); - setup_window_type(window); - set_window_size_hints(window); - set_window_opacity(window); + + /* Put the value of all properties we consider into effect */ + int i; + for (i = 0; property_table[i].name != NULL; i++) + { + (property_table[i].prop_change_fn)(window, &(property_table[i])); + } } +int +_xcwm_atom_change_to_event(xcb_atom_t atom, xcwm_window_t *window, xcwm_event_type_t *event) +{ + int i; + for (i = 0; property_table[i].name != NULL; i++) { + if (property_table[i].atom == atom) { + /* Take the value into consideration */ + (property_table[i].prop_change_fn)(window, &(property_table[i])); + + /* and translate to XCWM_ event */ + *event = property_table[i].event; + return 1; + } + } + + return 0; +} void -_xcwm_atoms_set_window_name(xcwm_window_t *window) +set_window_name(xcwm_window_t *window, xcwm_property_t *property) { xcb_get_property_cookie_t cookie; xcb_icccm_get_text_property_reply_t reply; @@ -270,7 +320,7 @@ _xcwm_atoms_set_wm_delete(xcwm_window_t *window) } static void -setup_window_type(xcwm_window_t *window) +setup_window_type(xcwm_window_t *window, xcwm_property_t *property) { xcb_get_property_cookie_t cookie; xcb_window_t transient; @@ -348,7 +398,7 @@ setup_window_type(xcwm_window_t *window) } void -set_window_size_hints(xcwm_window_t *window) +set_window_size_hints(xcwm_window_t *window, xcwm_property_t *property) { xcb_get_property_cookie_t cookie; cookie = xcb_icccm_get_wm_normal_hints(window->context->conn, @@ -361,10 +411,10 @@ set_window_size_hints(xcwm_window_t *window) } void -set_window_opacity(xcwm_window_t *window) +set_window_opacity(xcwm_window_t *window, xcwm_property_t *property) { xcb_get_property_cookie_t cookie; - cookie = xcb_get_property(window->context->conn, 0, window->window_id, window->context->atoms->wm_opacity_atom, XCB_ATOM_CARDINAL, 0L, 4L); + cookie = xcb_get_property(window->context->conn, 0, window->window_id, property->atom, XCB_ATOM_CARDINAL, 0L, 4L); xcb_get_property_reply_t *reply = xcb_get_property_reply(window->context->conn, cookie, NULL); if (reply) diff --git a/src/libxcwm/event_loop.c b/src/libxcwm/event_loop.c index 745707d..1d3f032 100644 --- a/src/libxcwm/event_loop.c +++ b/src/libxcwm/event_loop.c @@ -469,16 +469,21 @@ run_event_loop(void *thread_arg_struct) break; } - /* Change to window name */ - if (notify->atom == window->context->atoms->ewmh_conn._NET_WM_NAME - || notify->atom == window->context->atoms->wm_name_atom) { - _xcwm_atoms_set_window_name(window); + xcwm_event_type_t event; + if (_xcwm_atom_change_to_event(notify->atom, window, &event)) + { + /* Send the appropriate event */ return_evt = malloc(sizeof(xcwm_event_t)); - return_evt->event_type = XCWM_EVENT_WINDOW_NAME; + return_evt->event_type = event; return_evt->window = window; - callback_ptr(return_evt); - break; + } + else { + printf("PROPERTY_NOTIFY for ignored property atom %d\n", notify->atom); + /* + We need a mechanism to forward properties we don't know about to WM, + otherwise everything needs to be in libXcwm ...? + */ } break; diff --git a/src/libxcwm/xcwm_internal.h b/src/libxcwm/xcwm_internal.h index ffc0cbd..5124e45 100644 --- a/src/libxcwm/xcwm_internal.h +++ b/src/libxcwm/xcwm_internal.h @@ -52,10 +52,8 @@ typedef struct xcwm_event_connection { struct xcwm_wm_atoms_t { xcb_atom_t wm_delete_window_atom; xcb_atom_t wm_transient_for_atom; - xcb_atom_t wm_name_atom; xcb_atom_t wm_state_atom; xcb_ewmh_connection_t ewmh_conn; - xcb_atom_t wm_opacity_atom; }; /** @@ -302,13 +300,6 @@ void _xcwm_atoms_init_window(xcwm_window_t *window); /** - * Get and set the WM_NAME of the window. - * @param window The window - */ -void -_xcwm_atoms_set_window_name(xcwm_window_t *window); - -/** * Get the set the WM_DELETE_WINDOWatom for the winodw. * @param window The window. */ @@ -331,4 +322,14 @@ _xcwm_atoms_release(xcwm_context_t *context); void _xcwm_atoms_set_wm_state(xcwm_window_t *window, xcwm_window_state_t state); +/** + * Note change of a property atom, and look up corresponding event type + * @param window The property atom which has changed + * @param event The corresponding event type + * @return 0 if there is no corresponding event + */ +int +_xcwm_atom_change_to_event(xcb_atom_t atom, xcwm_window_t *window, xcwm_event_type_t *event); + + #endif /* _XCWM_INTERNAL_H_ */ |