diff options
author | Elijah Newren <newren@gmail.com> | 2005-06-16 17:32:36 +0000 |
---|---|---|
committer | Elijah Newren <newren@src.gnome.org> | 2005-06-16 17:32:36 +0000 |
commit | ef2b77a9f549758c749f06ca7d55a941e58805e2 (patch) | |
tree | a7f1b2bab64805fe85557ba35dc300aa22fcd036 | |
parent | 0aab171582dc6f1f47f78dce8243d8ca27f082f3 (diff) | |
download | libwnck-ef2b77a9f549758c749f06ca7d55a941e58805e2.tar.gz |
Add support for the Urgent hint; fixes #120439.
2005-06-16 Elijah Newren <newren@gmail.com>
Add support for the Urgent hint; fixes #120439.
* libwnck/selector.c (wnck_selector_get_window_name):
* libwnck/tasklist.c (wnck_task_popup_menu,
wnck_task_get_demands_attention, wnck_task_update_visibile_state,
wnck_task_create_widgets):
* libwnck/window.[ch] (wnck_window_demands_attention,
transient_demands_attention,
wnck_window_or_transient_demands_attention):
two function renames: (1) from
wnck_window_or_transient_demands_attention() to
wnck_window_or_transient_needs_attention(), and (2) from
-wnck_task_get_demands_attention() to
wnck_task_get_needs_attention()
* libwnck/selector.c (wnck_selector_window_state_changed):
* libwnck/tasklist.c (wnck_task_state_changed):
* libwnck/window.h (enum WnckWindowState):
add WNCK_WINDOW_STATE_URGENT and checks for it
* libwnck/window.c (COMPRESS_STATE macro): add
(window)->priv->is_urgent, (struct _WnckWindowPrivate): add
is_urgent_field and need_update_wmhints field),
(_wnck_window_create): provide default group leader but have
update_wmhints() do the actual setting if there is a different one
specified, (_wnck_window_process_property_notify): add need for
updating from WM_HINTS separate from icon_cache_property updating,
(update_state): looks like there's a bug here so throw in a FIXME
though I don't have time to check into it right now,
(update_wmclass): new function to get updates related to WM_HINTS
atom, (force_update_now): call update_wmhints()
* libwnck/xutils.h (_wnck_get_group_leader): remove this function
as it has been replaced by the more comprehensive update_wmhints()
in window.c
-rw-r--r-- | ChangeLog | 40 | ||||
-rw-r--r-- | libwnck/selector.c | 7 | ||||
-rw-r--r-- | libwnck/tasklist.c | 29 | ||||
-rw-r--r-- | libwnck/window.c | 95 | ||||
-rw-r--r-- | libwnck/window.h | 7 | ||||
-rw-r--r-- | libwnck/xutils.h | 1 |
6 files changed, 133 insertions, 46 deletions
@@ -1,3 +1,43 @@ +2005-06-16 Elijah Newren <newren@gmail.com> + + Add support for the Urgent hint; fixes #120439. + + * libwnck/selector.c (wnck_selector_get_window_name): + * libwnck/tasklist.c (wnck_task_popup_menu, + wnck_task_get_demands_attention, wnck_task_update_visibile_state, + wnck_task_create_widgets): + * libwnck/window.[ch] (wnck_window_demands_attention, + transient_demands_attention, + wnck_window_or_transient_demands_attention): + + two function renames: (1) from + wnck_window_or_transient_demands_attention() to + wnck_window_or_transient_needs_attention(), and (2) from + -wnck_task_get_demands_attention() to + wnck_task_get_needs_attention() + + * libwnck/selector.c (wnck_selector_window_state_changed): + * libwnck/tasklist.c (wnck_task_state_changed): + * libwnck/window.h (enum WnckWindowState): + + add WNCK_WINDOW_STATE_URGENT and checks for it + + * libwnck/window.c (COMPRESS_STATE macro): add + (window)->priv->is_urgent, (struct _WnckWindowPrivate): add + is_urgent_field and need_update_wmhints field), + (_wnck_window_create): provide default group leader but have + update_wmhints() do the actual setting if there is a different one + specified, (_wnck_window_process_property_notify): add need for + updating from WM_HINTS separate from icon_cache_property updating, + (update_state): looks like there's a bug here so throw in a FIXME + though I don't have time to check into it right now, + (update_wmclass): new function to get updates related to WM_HINTS + atom, (force_update_now): call update_wmhints() + + * libwnck/xutils.h (_wnck_get_group_leader): remove this function + as it has been replaced by the more comprehensive update_wmhints() + in window.c + 2005-06-07 Vincent Untz <vuntz@gnome.org> * configure.in: post-release bump to 2.11.4 diff --git a/libwnck/selector.c b/libwnck/selector.c index 796fb02..b9e91a6 100644 --- a/libwnck/selector.c +++ b/libwnck/selector.c @@ -219,7 +219,7 @@ wnck_selector_get_window_name (WnckWindow *window) else name = g_strdup (const_name); - if (wnck_window_or_transient_demands_attention (window)) + if (wnck_window_or_transient_needs_attention (window)) { return_value = g_strdup_printf ("<b>%s</b>", name); g_free (name); @@ -307,7 +307,8 @@ wnck_selector_window_state_changed (WnckWindow *window, (changed_mask & (WNCK_WINDOW_STATE_MINIMIZED | WNCK_WINDOW_STATE_SHADED | WNCK_WINDOW_STATE_SKIP_TASKLIST | - WNCK_WINDOW_STATE_DEMANDS_ATTENTION))) + WNCK_WINDOW_STATE_DEMANDS_ATTENTION | + WNCK_WINDOW_STATE_URGENT))) return; item = NULL; @@ -332,7 +333,7 @@ wnck_selector_window_state_changed (WnckWindow *window, if (changed_mask & (WNCK_WINDOW_STATE_MINIMIZED | WNCK_WINDOW_STATE_SHADED | - WNCK_WINDOW_STATE_DEMANDS_ATTENTION)) + WNCK_WINDOW_STATE_DEMANDS_ATTENTION | WNCK_WINDOW_STATE_URGENT)) { window_name = wnck_selector_get_window_name (window); gtk_label_set_text (GTK_LABEL (item->label), window_name); diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c index 85cf4d7..f69a383 100644 --- a/libwnck/tasklist.c +++ b/libwnck/tasklist.c @@ -200,7 +200,7 @@ static WnckTask *wnck_task_new_from_class_group (WnckTasklist *tasklist, static WnckTask *wnck_task_new_from_startup_sequence (WnckTasklist *tasklist, SnStartupSequence *sequence); #endif -static gboolean wnck_task_get_demands_attention (WnckTask *task); +static gboolean wnck_task_get_needs_attention (WnckTask *task); static char *wnck_task_get_text (WnckTask *task); @@ -2240,7 +2240,7 @@ wnck_task_popup_menu (WnckTask *task, text = wnck_task_get_text (win_task); menu_item = gtk_image_menu_item_new_with_label (text); - if (wnck_task_get_demands_attention (win_task)) + if (wnck_task_get_needs_attention (win_task)) make_gtk_label_bold (GTK_LABEL (GTK_BIN (menu_item)->child)); g_free (text); @@ -2544,13 +2544,13 @@ wnck_task_get_icon (WnckTask *task) } static gboolean -wnck_task_get_demands_attention (WnckTask *task) +wnck_task_get_needs_attention (WnckTask *task) { GList *l; WnckTask *win_task; - gboolean demands_attention; + gboolean needs_attention; - demands_attention = FALSE; + needs_attention = FALSE; switch (task->type) { @@ -2560,9 +2560,9 @@ wnck_task_get_demands_attention (WnckTask *task) { win_task = WNCK_TASK (l->data); - if (wnck_window_or_transient_demands_attention (win_task->window)) + if (wnck_window_or_transient_needs_attention (win_task->window)) { - demands_attention = TRUE; + needs_attention = TRUE; break; } @@ -2571,15 +2571,15 @@ wnck_task_get_demands_attention (WnckTask *task) break; case WNCK_TASK_WINDOW: - demands_attention = - wnck_window_or_transient_demands_attention (task->window); + needs_attention = + wnck_window_or_transient_needs_attention (task->window); break; case WNCK_TASK_STARTUP_SEQUENCE: break; } - return demands_attention != FALSE; + return needs_attention != FALSE; } static void @@ -2598,7 +2598,7 @@ wnck_task_update_visible_state (WnckTask *task) if (text != NULL) { gtk_label_set_text (GTK_LABEL (task->label), text); - if (wnck_task_get_demands_attention (task)) + if (wnck_task_get_needs_attention (task)) { make_gtk_label_bold ((GTK_LABEL (task->label))); wnck_task_queue_glow (task); @@ -2630,8 +2630,9 @@ wnck_task_state_changed (WnckWindow *window, return; } - if ((changed_mask & WNCK_WINDOW_STATE_MINIMIZED) || - (changed_mask & WNCK_WINDOW_STATE_DEMANDS_ATTENTION)) + if ((changed_mask & WNCK_WINDOW_STATE_MINIMIZED) || + (changed_mask & WNCK_WINDOW_STATE_DEMANDS_ATTENTION) || + (changed_mask & WNCK_WINDOW_STATE_URGENT)) { WnckTask *win_task; @@ -2854,7 +2855,7 @@ wnck_task_create_widgets (WnckTask *task) PANGO_ELLIPSIZE_END); gtk_label_set_max_width_chars (GTK_LABEL (task->label), MAX_WIDTH_CHARS); - if (wnck_task_get_demands_attention (task)) + if (wnck_task_get_needs_attention (task)) { make_gtk_label_bold ((GTK_LABEL (task->label))); wnck_task_queue_glow (task); diff --git a/libwnck/window.c b/libwnck/window.c index 226c2e9..6355fc8 100644 --- a/libwnck/window.c +++ b/libwnck/window.c @@ -47,7 +47,8 @@ static GHashTable *window_hash = NULL; ((window)->priv->is_sticky << 6) | \ ((window)->priv->is_hidden << 7) | \ ((window)->priv->is_fullscreen << 8) | \ - ((window)->priv->demands_attention << 9) ) + ((window)->priv->demands_attention << 9) | \ + ((window)->priv->is_urgent << 10) ) struct _WnckWindowPrivate { @@ -100,6 +101,7 @@ struct _WnckWindowPrivate guint is_hidden : 1; guint is_fullscreen : 1; guint demands_attention : 1; + guint is_urgent : 1; /* _NET_WM_STATE_HIDDEN doesn't map directly into an * externally-visible state (it determines the WM_STATE @@ -125,6 +127,7 @@ struct _WnckWindowPrivate guint need_update_transient_for : 1; guint need_update_startup_id : 1; guint need_update_wmclass : 1; + guint need_update_wmhints : 1; }; enum { @@ -376,8 +379,10 @@ _wnck_window_create (Window xwindow, _wnck_select_input (window->priv->xwindow, WNCK_APP_WINDOW_EVENT_MASK); - window->priv->group_leader = - _wnck_get_group_leader (window->priv->xwindow); + /* Default the group leader to the window itself; it is set in + * update_wmhints() if a different group leader is specified. + */ + window->priv->group_leader = window->priv->xwindow; window->priv->session_id = _wnck_get_session_id (window->priv->xwindow); @@ -404,6 +409,7 @@ _wnck_window_create (Window xwindow, window->priv->need_update_transient_for = TRUE; window->priv->need_update_startup_id = TRUE; window->priv->need_update_wmclass = TRUE; + window->priv->need_update_wmhints = TRUE; force_update_now (window); return window; @@ -610,26 +616,26 @@ wnck_window_is_minimized (WnckWindow *window) } /** - * wnck_window_demands_attention: + * wnck_window_needs_attention: * @window: a #WnckWindow * - * If the window has the demands attention state set returns - * %TRUE. This state may change anytime a state_changed signal gets - * emitted. + * If the window needs attention returns %TRUE. This state may change + * anytime a state_changed signal gets emitted, as it can depend on flags + * such as the demands_attention and is_urgent hints. * - * Return value: %TRUE if window has the demands_attention hint set + * Return value: %TRUE if window needs attention **/ gboolean -wnck_window_demands_attention (WnckWindow *window) +wnck_window_needs_attention (WnckWindow *window) { g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE); - return window->priv->demands_attention; + return window->priv->demands_attention || window->priv->is_urgent; } -/* Return whether one of the transients of @window demands attention */ +/* Return whether one of the transients of @window needs attention */ static gboolean -transient_demands_attention (WnckWindow *window) +transient_needs_attention (WnckWindow *window) { GList *windows; WnckWindow *transient; @@ -646,7 +652,7 @@ transient_demands_attention (WnckWindow *window) if (transient == window) return FALSE; - if (wnck_window_demands_attention (transient)) + if (wnck_window_needs_attention (transient)) return TRUE; } @@ -654,21 +660,19 @@ transient_demands_attention (WnckWindow *window) } /** - * wnck_window_or_transient_demands_attention: + * wnck_window_or_transient_needs_attention: * @window: a #WnckWindow * - * If the window or one of its transients has the demands attention - * state set returns %TRUE. This state may change anytime a - * state_changed signal gets emitted. + * If the window or one of its transients needs attention returns %TRUE. + * This state may change anytime a state_changed signal gets emitted. * - * Return value: %TRUE if window or one of its transients has the - * demands_attention hint set + * Return value: %TRUE if window or one of its transients needs attention **/ gboolean -wnck_window_or_transient_demands_attention (WnckWindow *window) +wnck_window_or_transient_needs_attention (WnckWindow *window) { - return wnck_window_demands_attention (window) || - transient_demands_attention (window); + return wnck_window_needs_attention (window) || + transient_needs_attention (window); } gboolean @@ -1616,14 +1620,18 @@ _wnck_window_process_property_notify (WnckWindow *window, else if (xevent->xproperty.atom == _wnck_atom_get ("_NET_WM_ICON") || xevent->xproperty.atom == - _wnck_atom_get ("KWM_WIN_ICON") || - xevent->xproperty.atom == - _wnck_atom_get ("WM_HINTS")) + _wnck_atom_get ("KWM_WIN_ICON")) { _wnck_icon_cache_property_changed (window->priv->icon_cache, xevent->xproperty.atom); queue_update (window); } + else if (xevent->xproperty.atom == + _wnck_atom_get ("WM_HINTS")) + { + window->priv->need_update_wmhints = TRUE; + queue_update (window); + } } void @@ -1756,6 +1764,9 @@ update_state (WnckWindow *window) break; } + /* FIXME!!!!!!!!!! What in the world is this buggy duplicate of the code + * immediately above this for??!?!? + */ switch (window->priv->wintype) { case WNCK_WINDOW_DESKTOP: @@ -2089,6 +2100,39 @@ update_wmclass (WnckWindow *window) } static void +update_wmhints (WnckWindow *window) +{ + XWMHints *hints; + + if (!window->priv->need_update_wmhints) + return; + + _wnck_error_trap_push (); + hints = XGetWMHints (gdk_display, window->priv->xwindow); + _wnck_error_trap_pop (); + + if (hints) + { + if ((hints->flags & IconPixmapHint) || + (hints->flags & IconMaskHint)) + _wnck_icon_cache_property_changed (window->priv->icon_cache, + _wnck_atom_get ("WM_HINTS")); + + if (hints->flags & WindowGroupHint) + window->priv->group_leader = hints->window_group; + + if (hints->flags & XUrgencyHint) + window->priv->is_urgent = TRUE; + else + window->priv->is_urgent = FALSE; + + XFree (hints); + } + + window->priv->need_update_wmhints = FALSE; +} + +static void force_update_now (WnckWindow *window) { WnckWindowState old_state; @@ -2143,6 +2187,7 @@ force_update_now (WnckWindow *window) update_startup_id (window); /* no side effects */ update_wmclass (window); + update_wmhints (window); update_transient_for (window); /* wintype needs this to be first */ update_wintype (window); update_wm_state (window); diff --git a/libwnck/window.h b/libwnck/window.h index a3ec07e..babe6ab 100644 --- a/libwnck/window.h +++ b/libwnck/window.h @@ -43,7 +43,8 @@ typedef enum WNCK_WINDOW_STATE_STICKY = 1 << 6, WNCK_WINDOW_STATE_HIDDEN = 1 << 7, WNCK_WINDOW_STATE_FULLSCREEN = 1 << 8, - WNCK_WINDOW_STATE_DEMANDS_ATTENTION = 1 << 9 + WNCK_WINDOW_STATE_DEMANDS_ATTENTION = 1 << 9, + WNCK_WINDOW_STATE_URGENT = 1 << 10, } WnckWindowState; typedef enum @@ -157,8 +158,8 @@ gboolean wnck_window_is_skip_pager (WnckWindow *window); gboolean wnck_window_is_skip_tasklist (WnckWindow *window); gboolean wnck_window_is_fullscreen (WnckWindow *window); gboolean wnck_window_is_sticky (WnckWindow *window); -gboolean wnck_window_demands_attention (WnckWindow *window); -gboolean wnck_window_or_transient_demands_attention (WnckWindow *window); +gboolean wnck_window_needs_attention (WnckWindow *window); +gboolean wnck_window_or_transient_needs_attention (WnckWindow *window); void wnck_window_set_skip_pager (WnckWindow *window, gboolean skip); diff --git a/libwnck/xutils.h b/libwnck/xutils.h index f1c6434..8d67145 100644 --- a/libwnck/xutils.h +++ b/libwnck/xutils.h @@ -109,7 +109,6 @@ void _wnck_change_viewport (Screen *screen, int x, int y); -Window _wnck_get_group_leader (Window xwindow); char* _wnck_get_session_id (Window xwindow); int _wnck_get_pid (Window xwindow); char* _wnck_get_name (Window xwindow); |