summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJess VanDerwalker <washu@sonic.net>2012-07-25 11:16:55 -0700
committerJess VanDerwalker <washu@sonic.net>2012-07-25 13:05:30 -0700
commitd80dff4e181f830753500257a5e3dfc99a4ee390 (patch)
treeba332a47771cde9e8a3cb005824af3a2ba11199a
parent5b1f36b97142f6fb3139e31e744fdf691ab4290c (diff)
libxcwm: Support for WM_TRANSIENT_FOR and WM_SIZE_HINTS added
Getting values of ICCCM properties has been changed to use the xcb_icccm.h functions available to simplify library code. On receiving a mapping event, WM_TRANSIENT_FOR and WM_SIZE_HINTS for window are checked for the window, and values in xcwm_window_t are set. Enumeration added for different EWMH window types, currently only XCWM_WINDOW_TYPE_DIALOG and XCWM_WINDOW_TYPE_NORMAL are used. A xcwm_sizing_t structure was added to hold WM_SIZE_HINT data for the window. Signed-off-by: Jess VanDerwalker <washu@sonic.net> Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
-rw-r--r--configure.ac2
-rw-r--r--include/xcwm/window.h63
-rw-r--r--src/libxcwm/window.c140
-rw-r--r--src/libxcwm/xcwm_internal.h1
4 files changed, 160 insertions, 46 deletions
diff --git a/configure.ac b/configure.ac
index bcb58fe..2db540d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@ AC_PROG_OBJC
AC_PROG_INSTALL
# Checks for libraries.
-PKG_CHECK_MODULES(XCB, xcb-damage xcb-composite xcb-event xcb-xtest xcb-image xcb-keysyms xcb-icccm xcb-atom)
+PKG_CHECK_MODULES(XCB, xcb-damage xcb-composite xcb-event xcb-xtest xcb-image xcb-keysyms xcb-icccm xcb-atom xcb-ewmh)
AC_CHECK_FUNC(dispatch_async,
AC_DEFINE([HAVE_LIBDISPATCH], 1, [Define to 1 if you have the libdispatch (GCD) available])
diff --git a/include/xcwm/window.h b/include/xcwm/window.h
index 71b5c2b..af2774d 100644
--- a/include/xcwm/window.h
+++ b/include/xcwm/window.h
@@ -41,14 +41,53 @@ struct xcwm_rect_t {
};
typedef struct xcwm_rect_t xcwm_rect_t;
+/**
+ * Enumeration for different possible window types
+ */
+enum xcwm_window_type_t {
+ XCWM_WINDOW_TYPE_UNKNOWN = 0,
+ XCWM_WINDOW_TYPE_COMBO,
+ XCWM_WINDOW_TYPE_DESKTOP,
+ XCWM_WINDOW_TYPE_DIALOG,
+ XCWM_WINDOW_TYPE_DND,
+ XCWM_WINDOW_TYPE_DOCK,
+ XCWM_WINDOW_TYPE_DROPDOWN_MENU,
+ XCWM_WINDOW_TYPE_MENU,
+ XCWM_WINDOW_TYPE_NORMAL,
+ XCWM_WINDOW_TYPE_NOTIFICATION,
+ XCWM_WINDOW_TYPE_POPUP_MENU,
+ XCWM_WINDOW_TYPE_SPLASH,
+ XCWM_WINDOW_TYPE_TOOLBAR,
+ XCWM_WINDOW_TYPE_TOOLTIP,
+ XCWM_WINDOW_TYPE_UTILITY,
+};
+typedef enum xcwm_window_type_t xcwm_window_type_t;
+
+/**
+ * Structure defining min/max size for window and resizing
+ * increments. A value of 0 in any field implies the field is unset.
+ */
+struct xcwm_window_sizing_t {
+ uint32_t min_width;
+ uint32_t min_height;
+ uint32_t max_width;
+ uint32_t max_height;
+ uint32_t width_inc;
+ uint32_t height_inc;
+};
+typedef struct xcwm_window_sizing_t xcwm_window_sizing_t;
+
/* Structure for holding data for a window */
struct xcwm_window_t {
xcb_drawable_t window_id;
xcwm_context_t *context;
+ xcwm_window_type_t type; /* The type of this window */
struct xcwm_window_t *parent;
+ struct xcwm_window_t *transient_for; /* Window this one is transient for */
xcb_damage_damage_t damage;
xcwm_rect_t *bounds;
xcwm_rect_t *dmg_bounds;
+ xcwm_window_sizing_t *sizing; /* Sizing information for the window */
char *name; /* The name of the window */
int wm_delete_set; /* Flag for WM_DELETE_WINDOW, 1 if set */
int override_redirect;
@@ -104,6 +143,14 @@ xcwm_window_configure(xcwm_window_t *window, int x, int y,
int height, int width);
/**
+ * Get the window's type.
+ * @param window Window to get type for.
+ * @return The type of the window.
+ */
+xcwm_window_type_t
+xcwm_window_get_window_type(xcwm_window_t const *window);
+
+/**
* Get the context for this window.
* @param window The window to get context from.
* @return The context of the window.
@@ -120,6 +167,14 @@ xcwm_window_t *
xcwm_window_get_parent(xcwm_window_t const *window);
/**
+ * Get the window the given window is transient for.
+ * @param window
+ * @return This windows "transient for" window, NULL if none.
+ */
+xcwm_window_t const *
+xcwm_window_get_transient_for(xcwm_window_t const *window);
+
+/**
* Determine if window has override redirect flag set.
* @param window
* @return 1 if override redirect set on window, else 0.
@@ -168,4 +223,12 @@ xcwm_window_get_damaged_rect(xcwm_window_t const *window);
char *
xcwm_window_copy_name(xcwm_window_t const *window);
+/**
+ * Get the sizing information for the window.
+ * @param window The window to get sizing data for.
+ * @return The structure containing the sizing data
+ */
+xcwm_window_sizing_t const *
+xcwm_window_get_sizing(xcwm_window_t const *window);
+
#endif /* _XCWM_WINDOW_H_ */
diff --git a/src/libxcwm/window.c b/src/libxcwm/window.c
index e5c6699..bf6c70c 100644
--- a/src/libxcwm/window.c
+++ b/src/libxcwm/window.c
@@ -29,6 +29,8 @@
#include <xcb/xfixes.h>
#include <xcb/damage.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_ewmh.h>
#include <xcwm/xcwm.h>
#include "xcwm_internal.h"
@@ -47,6 +49,10 @@ set_wm_name_in_context(xcb_connection_t *conn, xcwm_window_t *window);
void
set_wm_delete_win_in_context(xcb_connection_t *conn, xcwm_window_t *window);
+/* Determine values of window WM_SIZE_HINTS */
+void
+set_wm_size_hints_for_window(xcb_connection_t *conn, xcwm_window_t *window);
+
/* Initialize damage on a window */
void
init_damage_on_window(xcb_connection_t *conn, xcwm_window_t *window);
@@ -303,6 +309,13 @@ _xcwm_window_release(xcwm_window_t *window)
/* Accessor functions into xcwm_window_t */
+xcwm_window_type_t
+xcwm_window_get_window_type(xcwm_window_t const *window)
+{
+
+ return window->type;
+}
+
xcwm_context_t *
xcwm_window_get_context(xcwm_window_t const *window)
{
@@ -317,6 +330,13 @@ xcwm_window_get_parent(xcwm_window_t const *window)
return window->parent;
}
+xcwm_window_t const *
+xcwm_window_get_transient_for(xcwm_window_t const *window)
+{
+
+ return window->transient_for;
+}
+
int
xcwm_window_is_override_redirect(xcwm_window_t const *window)
{
@@ -359,6 +379,13 @@ xcwm_window_copy_name(xcwm_window_t const *window)
return strdup(window->name);
}
+xcwm_window_sizing_t const *
+xcwm_window_get_sizing(xcwm_window_t const *window)
+{
+
+ return window->sizing;
+}
+
/* Resize the window on server side */
void
_xcwm_resize_window(xcb_connection_t *conn, xcb_window_t window,
@@ -386,81 +413,104 @@ _xcwm_map_window(xcb_connection_t *conn, xcwm_window_t *window)
void
set_icccm_properties(xcb_connection_t *conn, xcwm_window_t *window)
{
+ xcb_get_property_cookie_t cookie;
+ xcb_window_t transient;
+ xcb_generic_error_t *error;
+ uint8_t success;
+
set_wm_name_in_context(conn, window);
set_wm_delete_win_in_context(conn, window);
+ set_wm_size_hints_for_window(conn, window);
+
+ /* Get the window this one is transient for */
+ cookie = xcb_icccm_get_wm_transient_for(conn, window->window_id);
+ success = xcb_icccm_get_wm_transient_for_reply(conn, cookie,
+ &transient, &error);
+ if (success) {
+ window->transient_for = _xcwm_get_window_node_by_window_id(transient);
+ /* FIXME: Currently we assume that any window that is
+ * transient for another is a dialog. */
+ window->type = XCWM_WINDOW_TYPE_DIALOG;
+ } else {
+ window->transient_for = NULL;
+ window->type = XCWM_WINDOW_TYPE_NORMAL;
+ }
}
void
set_wm_name_in_context(xcb_connection_t *conn, xcwm_window_t *window)
{
xcb_get_property_cookie_t cookie;
- xcb_get_property_reply_t *reply;
+ xcb_icccm_get_text_property_reply_t reply;
xcb_generic_error_t *error;
- char *value;
- int length;
-
- cookie = xcb_get_property(conn,
- 0,
- window->window_id,
- XCB_ATOM_WM_NAME,
- XCB_GET_PROPERTY_TYPE_ANY,
- 0,
- 128);
- reply = xcb_get_property_reply(conn, cookie, &error);
- if (!reply) {
- window->name = NULL;
+
+ cookie = xcb_icccm_get_wm_name(conn, window->window_id);
+ if (!xcb_icccm_get_wm_name_reply(conn, cookie, &reply, &error)) {
+ window->name = malloc(sizeof(char));
+ window->name[0] = '\0';
return;
}
- length = xcb_get_property_value_length(reply);
- value = (char *)xcb_get_property_value(reply);
- window->name = malloc(sizeof(char) * (length + 1));
- strncpy(window->name, value, length);
- window->name[length] = '\0';
+ window->name = malloc(sizeof(char) * (reply.name_len + 1));
+ strncpy(window->name, reply.name, reply.name_len);
+ window->name[reply.name_len] = '\0';
+ xcb_icccm_get_text_property_reply_wipe(&reply);
}
void
set_wm_delete_win_in_context(xcb_connection_t *conn, xcwm_window_t *window)
{
xcb_get_property_cookie_t cookie;
- xcb_get_property_reply_t *reply;
- xcb_atom_t *prop_atoms;
- int prop_length;
+ xcb_icccm_get_wm_protocols_reply_t reply;
xcb_generic_error_t *error;
int i;
/* Get the WM_PROTOCOLS */
- cookie = xcb_get_property(conn,
- 0,
- window->window_id,
- _wm_atoms->wm_protocols_atom,
- XCB_ATOM_ATOM,
- 0,
- UINT_MAX);
-
- reply = xcb_get_property_reply(conn, cookie, &error);
-
- if (!reply) {
+ cookie = xcb_icccm_get_wm_protocols(conn, window->window_id,
+ _wm_atoms->wm_protocols_atom);
+
+ if (xcb_icccm_get_wm_protocols_reply(conn, cookie, &reply, &error) == 1) {
+ /* See if the WM_DELETE_WINDOW is in WM_PROTOCOLS */
+ for (i = 0; i < reply.atoms_len; i++) {
+ if (reply.atoms[i] == _wm_atoms->wm_delete_window_atom) {
+ window->wm_delete_set = 1;
+ break;
+ }
+ }
+ } else {
window->wm_delete_set = 0;
return;
}
- prop_length = xcb_get_property_value_length(reply);
- prop_atoms = (xcb_atom_t *)xcb_get_property_value(reply);
- free(reply);
-
- /* See if the WM_DELETE_WINDOW is in WM_PROTOCOLS */
- for (i = 0; i < prop_length; i++) {
- if (prop_atoms[i] == _wm_atoms->wm_delete_window_atom) {
- window->wm_delete_set = 1;
- return;
- }
- }
- window->wm_delete_set = 0;
+ xcb_icccm_get_wm_protocols_reply_wipe(&reply);
return;
}
void
+set_wm_size_hints_for_window(xcb_connection_t *conn, xcwm_window_t *window)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_size_hints_t hints;
+
+ if (window->sizing) {
+ free(window->sizing);
+ }
+ window->sizing = malloc(sizeof(xcwm_window_sizing_t));
+ assert(window->sizing);
+ cookie = xcb_icccm_get_wm_normal_hints(conn, window->window_id);
+ if (!xcb_icccm_get_wm_normal_hints_reply(conn, cookie, &hints, NULL)) {
+ memset(window->sizing, 0, sizeof(*window->sizing);
+ return;
+ }
+ window->sizing->min_width = hints.min_width;
+ window->sizing->min_height = hints.min_height;;
+ window->sizing->max_width = hints.max_width;
+ window->sizing->max_height = hints.max_height;
+ window->sizing->width_inc = hints.width_inc;
+ window->sizing->height_inc = hints.height_inc;
+}
+
+void
init_damage_on_window(xcb_connection_t *conn, xcwm_window_t *window)
{
xcb_damage_damage_t damage_id;
diff --git a/src/libxcwm/xcwm_internal.h b/src/libxcwm/xcwm_internal.h
index 5bd58f9..ab149e5 100644
--- a/src/libxcwm/xcwm_internal.h
+++ b/src/libxcwm/xcwm_internal.h
@@ -52,6 +52,7 @@ typedef struct xcwm_event_connetion {
typedef struct xcwm_wm_atoms {
xcb_atom_t wm_protocols_atom;
xcb_atom_t wm_delete_window_atom;
+ xcb_atom_t wm_transient_for_atom;
} xcwm_wm_atoms;
/**