diff options
author | Vincent Untz <vuntz@gnome.org> | 2007-06-10 16:22:42 +0000 |
---|---|---|
committer | Vincent Untz <vuntz@src.gnome.org> | 2007-06-10 16:22:42 +0000 |
commit | 8fa017999ac1af53387207bc76edc284b67b303b (patch) | |
tree | c0fdf593319c2f02eac486f5edf07757bd184111 | |
parent | ccae521e4f7794b1eec3f94d97eca0732c862372 (diff) | |
download | libwnck-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-- | ChangeLog | 29 | ||||
-rw-r--r-- | doc/libwnck-sections.txt | 1 | ||||
-rw-r--r-- | doc/tmpl/window.sgml | 12 | ||||
-rw-r--r-- | libwnck/window.c | 123 | ||||
-rw-r--r-- | libwnck/window.h | 5 | ||||
-rw-r--r-- | libwnck/xutils.c | 54 | ||||
-rw-r--r-- | libwnck/xutils.h | 6 |
7 files changed, 210 insertions, 20 deletions
@@ -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); |