summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Untz <vuntz@gnome.org>2007-06-10 16:22:42 +0000
committerVincent Untz <vuntz@src.gnome.org>2007-06-10 16:22:42 +0000
commit8fa017999ac1af53387207bc76edc284b67b303b (patch)
treec0fdf593319c2f02eac486f5edf07757bd184111
parentccae521e4f7794b1eec3f94d97eca0732c862372 (diff)
downloadlibwnck-8fa017999ac1af53387207bc76edc284b67b303b.tar.gz
Add support for _NET_FRAME_EXTENTS. This adds a new API. Fix bug #351055.
2007-06-10 Vincent Untz <vuntz@gnome.org> Add support for _NET_FRAME_EXTENTS. This adds a new API. Fix bug #351055. * doc/libwnck-sections.txt: updated for wnck_window_get_client_window_geometry() * doc/tmpl/window.sgml: ditto * libwnck/window.[ch]: (_wnck_window_create): we need to update the information about frame. (wnck_window_get_client_window_geometry): new, returns the geometry of the window without the frame (that's the "real" X geometry) (wnck_window_get_geometry): changed to return the geometry of the window with its frame. That's a small change in the API meaning, but we're unstable, aren't we? :-) (wnck_window_is_in_viewport): take into account the frame of the window (_wnck_window_process_property_notify): check if we need to update the frame info (update_icon_name): move some code into xutils.c, to make this function more like update_name() (update_frame_extents): new, gets the frame info and emit a geometry changed signal if the info changed (force_update_now): * libwnck/xutils.[ch]: (_wnck_get_icon_name): new, works like _wnck_get_name() (_wnck_get_frame_extents): new, gets the frame info from the _NET_FRAME_EXTENTS hint svn path=/trunk/; revision=1296
-rw-r--r--ChangeLog29
-rw-r--r--doc/libwnck-sections.txt1
-rw-r--r--doc/tmpl/window.sgml12
-rw-r--r--libwnck/window.c123
-rw-r--r--libwnck/window.h5
-rw-r--r--libwnck/xutils.c54
-rw-r--r--libwnck/xutils.h6
7 files changed, 210 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 177a405..7322f1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,34 @@
2007-06-10 Vincent Untz <vuntz@gnome.org>
+ Add support for _NET_FRAME_EXTENTS. This adds a new API.
+ Fix bug #351055.
+
+ * doc/libwnck-sections.txt: updated for
+ wnck_window_get_client_window_geometry()
+ * doc/tmpl/window.sgml: ditto
+ * libwnck/window.[ch]: (_wnck_window_create): we need to update the
+ information about frame.
+ (wnck_window_get_client_window_geometry): new, returns the geometry of
+ the window without the frame (that's the "real" X geometry)
+ (wnck_window_get_geometry): changed to return the geometry of the
+ window with its frame. That's a small change in the API meaning, but
+ we're unstable, aren't we? :-)
+ (wnck_window_is_in_viewport): take into account the frame of the
+ window
+ (_wnck_window_process_property_notify): check if we need to update the
+ frame info
+ (update_icon_name): move some code into xutils.c, to make this
+ function more like update_name()
+ (update_frame_extents): new, gets the frame info and emit a geometry
+ changed signal if the info changed
+ (force_update_now):
+ * libwnck/xutils.[ch]: (_wnck_get_icon_name): new, works like
+ _wnck_get_name()
+ (_wnck_get_frame_extents): new, gets the frame info from the
+ _NET_FRAME_EXTENTS hint
+
+2007-06-10 Vincent Untz <vuntz@gnome.org>
+
* libwnck/window.c: (update_actions): add WNCK_WINDOW_ACTION_BELOW to
the available actions if we couldn't get the list of available actions.
diff --git a/doc/libwnck-sections.txt b/doc/libwnck-sections.txt
index 0ffbd98..32524ad 100644
--- a/doc/libwnck-sections.txt
+++ b/doc/libwnck-sections.txt
@@ -77,6 +77,7 @@ wnck_window_transient_is_most_recently_activated
wnck_window_set_icon_geometry
WnckWindowGravity
WnckWindowMoveResizeMask
+wnck_window_get_client_window_geometry
wnck_window_get_geometry
wnck_window_set_geometry
wnck_window_keyboard_move
diff --git a/doc/tmpl/window.sgml b/doc/tmpl/window.sgml
index 1b7d2de..f1c776c 100644
--- a/doc/tmpl/window.sgml
+++ b/doc/tmpl/window.sgml
@@ -747,6 +747,18 @@ WnckWindow
@WNCK_WINDOW_CHANGE_WIDTH:
@WNCK_WINDOW_CHANGE_HEIGHT:
+<!-- ##### FUNCTION wnck_window_get_client_window_geometry ##### -->
+<para>
+
+</para>
+
+@window:
+@xp:
+@yp:
+@widthp:
+@heightp:
+
+
<!-- ##### FUNCTION wnck_window_get_geometry ##### -->
<para>
diff --git a/libwnck/window.c b/libwnck/window.c
index 666ff3f..7933090 100644
--- a/libwnck/window.c
+++ b/libwnck/window.c
@@ -97,6 +97,11 @@ struct _WnckWindowPrivate
int width;
int height;
+ int left_frame;
+ int right_frame;
+ int top_frame;
+ int bottom_frame;
+
char *startup_id;
char *res_class;
@@ -145,6 +150,7 @@ struct _WnckWindowPrivate
guint need_update_startup_id : 1;
guint need_update_wmclass : 1;
guint need_update_wmhints : 1;
+ guint need_update_frame_extents : 1;
guint need_emit_name_changed : 1;
guint need_emit_icon_changed : 1;
@@ -185,6 +191,7 @@ static void update_wintype (WnckWindow *window);
static void update_transient_for (WnckWindow *window);
static void update_startup_id (WnckWindow *window);
static void update_wmclass (WnckWindow *window);
+static void update_frame_extents (WnckWindow *window);
static void unqueue_update (WnckWindow *window);
static void queue_update (WnckWindow *window);
static void force_update_now (WnckWindow *window);
@@ -480,6 +487,7 @@ _wnck_window_create (Window xwindow,
window->priv->need_update_startup_id = TRUE;
window->priv->need_update_wmclass = TRUE;
window->priv->need_update_wmhints = TRUE;
+ window->priv->need_update_frame_extents = TRUE;
window->priv->need_emit_name_changed = FALSE;
window->priv->need_emit_icon_changed = FALSE;
force_update_now (window);
@@ -1946,7 +1954,7 @@ wnck_window_get_state (WnckWindow *window)
}
/**
- * wnck_window_get_geometry:
+ * wnck_window_get_client_window_geometry:
* @window: a #WnckWindow.
* @xp: return location for X coordinate in pixels of @window.
* @yp: return location for Y coordinate in pixels of @window.
@@ -1957,6 +1965,49 @@ wnck_window_get_state (WnckWindow *window)
* in a ConfigureNotify event (i.e. this call does not round-trip
* to the server, just gets the last size we were notified of).
* The X and Y coordinates are relative to the root window.
+ *
+ * The window manager usually adds a frame around windows. If
+ * you need to know the size of @window with the frame, use
+ * wnck_window_get_geometry().
+ *
+ * Since: 2.20
+ **/
+void
+wnck_window_get_client_window_geometry (WnckWindow *window,
+ int *xp,
+ int *yp,
+ int *widthp,
+ int *heightp)
+{
+ g_return_if_fail (WNCK_IS_WINDOW (window));
+
+ if (xp)
+ *xp = window->priv->x;
+ if (yp)
+ *yp = window->priv->y;
+ if (widthp)
+ *widthp = window->priv->width;
+ if (heightp)
+ *heightp = window->priv->height;
+}
+
+/**
+ * wnck_window_get_geometry:
+ * @window: a #WnckWindow.
+ * @xp: return location for X coordinate in pixels of @window.
+ * @yp: return location for Y coordinate in pixels of @window.
+ * @widthp: return location for width in pixels of @window.
+ * @heightp: return location for height in pixels of @window.
+ *
+ * Gets the size and position of @window, including decorations. This
+ * function uses the information last received in a ConfigureNotify
+ * event and adjusts it according to the size of the frame that is
+ * added by the window manager (this call does not round-trip to the
+ * server, it just gets the last sizes that were notified). The
+ * X and Y coordinates are relative to the root window.
+ *
+ * If you need to know the actual size of @window ignoring the frame
+ * added by the window manager, use wnck_window_get_client_window_geometry().
**/
void
wnck_window_get_geometry (WnckWindow *window,
@@ -1968,13 +2019,13 @@ wnck_window_get_geometry (WnckWindow *window,
g_return_if_fail (WNCK_IS_WINDOW (window));
if (xp)
- *xp = window->priv->x;
+ *xp = window->priv->x - window->priv->left_frame;
if (yp)
- *yp = window->priv->y;
+ *yp = window->priv->y - window->priv->top_frame;
if (widthp)
- *widthp = window->priv->width;
+ *widthp = window->priv->width + window->priv->left_frame + window->priv->right_frame;
if (heightp)
- *heightp = window->priv->height;
+ *heightp = window->priv->height + window->priv->top_frame + window->priv->bottom_frame;
}
/**
@@ -1989,6 +2040,13 @@ wnck_window_get_geometry (WnckWindow *window,
*
* Sets the size and position of @window. The X and Y coordinates should be
* relative to the root window.
+ *
+ * Note that the new size and position apply to @window with its frame added
+ * by the window manager. Therefore, using wnck_window_set_geometry() with
+ * the values returned by wnck_window_get_geometry() should be a no-op, while
+ * using wnck_window_set_geometry() with the values returned by
+ * wnck_window_get_client_window_geometry() should reduce the size of @window
+ * and move it.
**/
void
wnck_window_set_geometry (WnckWindow *window,
@@ -2126,10 +2184,10 @@ wnck_window_is_in_viewport (WnckWindow *window,
viewport_rect.width = wnck_screen_get_width (window->priv->screen);
viewport_rect.height = wnck_screen_get_height (window->priv->screen);
- window_rect.x = window->priv->x + viewport_rect.x;
- window_rect.y = window->priv->y + viewport_rect.y;
- window_rect.width = window->priv->width;
- window_rect.height = window->priv->height;
+ window_rect.x = window->priv->x - window->priv->left_frame + viewport_rect.x;
+ window_rect.y = window->priv->y - window->priv->top_frame + viewport_rect.y;
+ window_rect.width = window->priv->width + window->priv->left_frame + window->priv->right_frame;
+ window_rect.height = window->priv->height + window->priv->top_frame + window->priv->bottom_frame;
return gdk_rectangle_intersect (&viewport_rect, &window_rect, &window_rect);
}
@@ -2249,6 +2307,12 @@ _wnck_window_process_property_notify (WnckWindow *window,
window->priv->need_update_wmhints = TRUE;
queue_update (window);
}
+ else if (xevent->xproperty.atom ==
+ _wnck_atom_get ("_NET_FRAME_EXTENTS"))
+ {
+ window->priv->need_update_frame_extents = TRUE;
+ queue_update (window);
+ }
}
void
@@ -2461,17 +2525,7 @@ update_icon_name (WnckWindow *window)
window->priv->need_update_icon_name = FALSE;
- if (new_name == NULL)
- new_name = _wnck_get_utf8_property (window->priv->xwindow,
- _wnck_atom_get ("_NET_WM_VISIBLE_ICON_NAME"));
-
- if (new_name == NULL)
- new_name = _wnck_get_utf8_property (window->priv->xwindow,
- _wnck_atom_get ("_NET_WM_ICON_NAME"));
-
- if (new_name == NULL)
- new_name = _wnck_get_text_property (window->priv->xwindow,
- XA_WM_ICON_NAME);
+ new_name = _wnck_get_icon_name (window->priv->xwindow);
if (!nullstr_equal (window->priv->icon_name, new_name))
window->priv->need_emit_name_changed = TRUE;
@@ -2772,6 +2826,34 @@ update_wmhints (WnckWindow *window)
}
static void
+update_frame_extents (WnckWindow *window)
+{
+ int left, right, top, bottom;
+
+ if (!window->priv->need_update_frame_extents)
+ return;
+
+ window->priv->need_update_frame_extents = FALSE;
+
+ if (!_wnck_get_frame_extents (window->priv->xwindow,
+ &left, &right, &top, &bottom))
+ return;
+
+ if (left != window->priv->left_frame ||
+ right != window->priv->right_frame ||
+ top != window->priv->top_frame ||
+ bottom != window->priv->bottom_frame)
+ {
+ window->priv->left_frame = left;
+ window->priv->right_frame = right;
+ window->priv->top_frame = top;
+ window->priv->bottom_frame = bottom;
+
+ emit_geometry_changed (window);
+ }
+}
+
+static void
force_update_now (WnckWindow *window)
{
WnckWindowState old_state;
@@ -2806,6 +2888,7 @@ force_update_now (WnckWindow *window)
*/
update_workspace (window); /* emits signals */
update_actions (window);
+ update_frame_extents (window); /* emits signals */
get_icons (window);
diff --git a/libwnck/window.h b/libwnck/window.h
index bf6bdb4..15e826d 100644
--- a/libwnck/window.h
+++ b/libwnck/window.h
@@ -371,6 +371,11 @@ void wnck_window_set_icon_geometry (WnckWindow *window,
WnckWindowActions wnck_window_get_actions (WnckWindow *window);
WnckWindowState wnck_window_get_state (WnckWindow *window);
+void wnck_window_get_client_window_geometry (WnckWindow *window,
+ int *xp,
+ int *yp,
+ int *widthp,
+ int *heightp);
void wnck_window_get_geometry (WnckWindow *window,
int *xp,
int *yp,
diff --git a/libwnck/xutils.c b/libwnck/xutils.c
index 9a64e70..14d4617 100644
--- a/libwnck/xutils.c
+++ b/libwnck/xutils.c
@@ -1141,6 +1141,25 @@ _wnck_get_name (Window xwindow)
return name;
}
+char*
+_wnck_get_icon_name (Window xwindow)
+{
+ char *name;
+
+ name = _wnck_get_utf8_property (xwindow,
+ _wnck_atom_get ("_NET_WM_VISIBLE_ICON_NAME"));
+
+ if (name == NULL)
+ name = _wnck_get_utf8_property (xwindow,
+ _wnck_atom_get ("_NET_WM_ICON_NAME"));
+
+ if (name == NULL)
+ name = _wnck_get_text_property (xwindow,
+ XA_WM_ICON_NAME);
+
+ return name;
+}
+
static char*
latin1_to_utf8 (const char *latin1)
{
@@ -1212,6 +1231,41 @@ _wnck_get_wmclass (Window xwindow,
}
}
+gboolean
+_wnck_get_frame_extents (Window xwindow,
+ int *left_frame,
+ int *right_frame,
+ int *top_frame,
+ int *bottom_frame)
+{
+ gulong *p_size;
+ int n_size;
+ gboolean retval;
+
+ retval = FALSE;
+ p_size = NULL;
+ n_size = 0;
+
+ _wnck_get_cardinal_list (xwindow,
+ _wnck_atom_get ("_NET_FRAME_EXTENTS"),
+ &p_size, &n_size);
+
+ if (p_size != NULL && n_size == 4)
+ {
+ *left_frame = p_size[0];
+ *right_frame = p_size[1];
+ *top_frame = p_size[2];
+ *bottom_frame = p_size[3];
+
+ retval = TRUE;
+ }
+
+ if (p_size != NULL)
+ g_free (p_size);
+
+ return retval;
+}
+
void
_wnck_select_input (Window xwindow,
int mask)
diff --git a/libwnck/xutils.h b/libwnck/xutils.h
index fbc1bee..bc54cd8 100644
--- a/libwnck/xutils.h
+++ b/libwnck/xutils.h
@@ -113,10 +113,16 @@ void _wnck_change_viewport (Screen *screen,
char* _wnck_get_session_id (Window xwindow);
int _wnck_get_pid (Window xwindow);
char* _wnck_get_name (Window xwindow);
+char* _wnck_get_icon_name (Window xwindow);
char* _wnck_get_res_class_utf8 (Window xwindow);
void _wnck_get_wmclass (Window xwindow,
char **res_class,
char **res_name);
+gboolean _wnck_get_frame_extents (Window xwindow,
+ int *left_frame,
+ int *right_frame,
+ int *top_frame,
+ int *bottom_frame);
void _wnck_select_input (Window xwindow,
int mask);