summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2005-06-16 17:32:36 +0000
committerElijah Newren <newren@src.gnome.org>2005-06-16 17:32:36 +0000
commitef2b77a9f549758c749f06ca7d55a941e58805e2 (patch)
treea7f1b2bab64805fe85557ba35dc300aa22fcd036
parent0aab171582dc6f1f47f78dce8243d8ca27f082f3 (diff)
downloadlibwnck-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--ChangeLog40
-rw-r--r--libwnck/selector.c7
-rw-r--r--libwnck/tasklist.c29
-rw-r--r--libwnck/window.c95
-rw-r--r--libwnck/window.h7
-rw-r--r--libwnck/xutils.h1
6 files changed, 133 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index dcfac6a..1433fea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);