summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2012-11-05 19:22:34 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2012-11-21 14:02:56 +0000
commitf3d5b07eb239e1d0206bbfaafeb6873aa044bf12 (patch)
treeb0f3143732345199d2fd2606cf9842c29c9bb1fe
parent0cfdc429539986a841036dbfcd87f825f52e0a87 (diff)
First pass at a general mechanism for signaling XCWM_ events when a property of interest changes
-rw-r--r--include/xcwm/event.h3
-rw-r--r--src/libxcwm/atoms.c86
-rw-r--r--src/libxcwm/event_loop.c19
-rw-r--r--src/libxcwm/xcwm_internal.h19
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_ */