summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2005-02-20 23:30:35 +0000
committerElijah Newren <newren@src.gnome.org>2005-02-20 23:30:35 +0000
commit8ba82411718ddfe70e3676d12a7f225a4bbe2965 (patch)
treefcf9c7a0e7c6c81d712fc9d96127b14ec7b23311
parentb398517581b59766ed26518b3caecdc4833d020c (diff)
downloadlibwnck-8ba82411718ddfe70e3676d12a7f225a4bbe2965.tar.gz
Handle the changes to _NET_ACTIVE_WINDOW from bug 128380 (made in order to
2005-02-20 Elijah Newren <newren@gmail.com> Handle the changes to _NET_ACTIVE_WINDOW from bug 128380 (made in order to match the agreed upon official behavior of that EWMH message), make relevant functions take a timestamp parameter, and add a timestamp to the _NET_CURRENT_DESKTOP message. Fixes all libwnck issues pointed out in #128380 and #161361. * libwnck/xutils.[ch]: (_wnck_activate): take a timestamp parameter to avoid bugs from using gtk_get_current_event_time, (_wnck_activate_workspace): likewise * libwnck/pager_accessible.c: * libwnck/pager.c: * libwnck/private.h: * libwnck/tasklist.c: * libwnck/window-action-menu.c: * libwnck/window.c: * libwnck/window.h: * libwnck/workspace.c: * libwnck/workspace.h: * test/test-wnck.c: Handle the need for passing timestamps to _wnck_activate and _wnck_activate_workspace (i.e. for _NET_ACTIVE_WINDOW and _NET_CURRENT_DESKTOP messages) * libwnck/tasklist.c: Manual moving of windows to a different workspace now occurs under different circumstances with the _NET_ACTIVE_WINDOW behavior change. * libwnck/selector.c: With the new _NET_ACTIVE_WINDOW behavior, only wnck_window_activate() is needed now. * configure.in: Increment LIBWNCK_CURRENT because of the API changes.
-rw-r--r--ChangeLog38
-rw-r--r--configure.in2
-rw-r--r--libwnck/pager-accessible.c3
-rw-r--r--libwnck/pager.c14
-rw-r--r--libwnck/private.h3
-rw-r--r--libwnck/selector.c11
-rw-r--r--libwnck/tasklist.c61
-rw-r--r--libwnck/test-wnck.c12
-rw-r--r--libwnck/window-action-menu.c4
-rw-r--r--libwnck/window.c18
-rw-r--r--libwnck/window.h11
-rw-r--r--libwnck/workspace.c7
-rw-r--r--libwnck/workspace.h3
-rw-r--r--libwnck/xutils.c15
-rw-r--r--libwnck/xutils.h6
15 files changed, 140 insertions, 68 deletions
diff --git a/ChangeLog b/ChangeLog
index 8d31c3b..a9614cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2005-02-20 Elijah Newren <newren@gmail.com>
+
+ Handle the changes to _NET_ACTIVE_WINDOW from bug 128380 (made in
+ order to match the agreed upon official behavior of that EWMH
+ message), make relevant functions take a timestamp parameter, and
+ add a timestamp to the _NET_CURRENT_DESKTOP message. Fixes all
+ libwnck issues pointed out in #128380 and #161361.
+
+ * libwnck/xutils.[ch]: (_wnck_activate): take a timestamp parameter
+ to avoid bugs from using gtk_get_current_event_time,
+ (_wnck_activate_workspace): likewise
+
+ * libwnck/pager_accessible.c:
+ * libwnck/pager.c:
+ * libwnck/private.h:
+ * libwnck/tasklist.c:
+ * libwnck/window-action-menu.c:
+ * libwnck/window.c:
+ * libwnck/window.h:
+ * libwnck/workspace.c:
+ * libwnck/workspace.h:
+ * test/test-wnck.c:
+ Handle the need for passing timestamps to _wnck_activate and
+ _wnck_activate_workspace (i.e. for _NET_ACTIVE_WINDOW and
+ _NET_CURRENT_DESKTOP messages)
+
+ * libwnck/tasklist.c:
+ Manual moving of windows to a different workspace now occurs under
+ different circumstances with the _NET_ACTIVE_WINDOW behavior
+ change.
+
+ * libwnck/selector.c:
+ With the new _NET_ACTIVE_WINDOW behavior, only
+ wnck_window_activate() is needed now.
+
+ * configure.in:
+ Increment LIBWNCK_CURRENT because of the API changes.
+
2005-02-12 Elijah Newren <newren@gmail.com>
Check for whether a window or one of its transients has the
diff --git a/configure.in b/configure.in
index f1edd54..3ed87ca 100644
--- a/configure.in
+++ b/configure.in
@@ -8,7 +8,7 @@ AM_MAINTAINER_MODE
dnl libtool versioning for libwnck
dnl increment if the interface has additions, changes, removals.
-LIBWNCK_CURRENT=15
+LIBWNCK_CURRENT=16
dnl increment any time the source changes; set to
dnl 0 if you increment CURRENT
diff --git a/libwnck/pager-accessible.c b/libwnck/pager-accessible.c
index 9941f65..134dab9 100644
--- a/libwnck/pager-accessible.c
+++ b/libwnck/pager-accessible.c
@@ -169,7 +169,8 @@ wnck_pager_add_selection (AtkSelection *selection,
* Activate the following worksapce as current workspace
*/
wspace = _wnck_pager_get_workspace (pager, i);
- _wnck_pager_activate_workspace (wspace);
+ /* FIXME: Is gtk_get_current_event_time() good enough here? I have no idea */
+ _wnck_pager_activate_workspace (wspace, gtk_get_current_event_time ());
return TRUE;
}
diff --git a/libwnck/pager.c b/libwnck/pager.c
index ebd6b4c..cec4914 100644
--- a/libwnck/pager.c
+++ b/libwnck/pager.c
@@ -63,6 +63,7 @@ struct _WnckPagerPrivate
guint dnd_activate;
gint dnd_workspace_number;
+ guint dnd_time;
};
enum
@@ -1126,7 +1127,7 @@ wnck_pager_drag_motion_timeout (gpointer data)
if (dnd_workspace &&
(pager->priv->dnd_workspace_number != wnck_workspace_get_number (active_workspace)))
- wnck_workspace_activate (dnd_workspace);
+ wnck_workspace_activate (dnd_workspace, pager->priv->dnd_time);
return FALSE;
}
@@ -1148,6 +1149,7 @@ wnck_pager_drag_motion (GtkWidget *widget,
pager);
pager->priv->dnd_workspace_number = workspace_at_point (pager, x, y, NULL, NULL);
+ pager->priv->dnd_time = time;
gdk_drag_status (context, 0, time);
return (pager->priv->dnd_workspace_number != -1);
@@ -1166,6 +1168,7 @@ wnck_pager_drag_motion_leave (GtkWidget *widget,
{
g_source_remove (pager->priv->dnd_activate);
pager->priv->dnd_workspace_number = -1;
+ pager->priv->dnd_time = 0;
pager->priv->dnd_activate = 0;
}
}
@@ -1225,7 +1228,7 @@ wnck_pager_button_release (GtkWidget *widget,
wnck_window_move_to_workspace (pager->priv->drag_window,
space);
if (space == wnck_screen_get_active_workspace (pager->priv->screen))
- wnck_window_activate (pager->priv->drag_window);
+ wnck_window_activate (pager->priv->drag_window, event->time);
}
}
@@ -1242,7 +1245,7 @@ wnck_pager_button_release (GtkWidget *widget,
/* Don't switch the desktop if we're already there */
if (space != wnck_screen_get_active_workspace (pager->priv->screen))
- wnck_workspace_activate (space);
+ wnck_workspace_activate (space, event->time);
/* EWMH only lets us move the viewport for the active workspace,
* but we just go ahead and hackily assume that the activate
@@ -1859,9 +1862,10 @@ _wnck_pager_get_workspace (WnckPager *pager,
}
void
-_wnck_pager_activate_workspace (WnckWorkspace *wspace)
+_wnck_pager_activate_workspace (WnckWorkspace *wspace,
+ guint32 timestamp)
{
- wnck_workspace_activate (wspace);
+ wnck_workspace_activate (wspace, timestamp);
}
void
diff --git a/libwnck/private.h b/libwnck/private.h
index 38e4cfd..0ad2eff 100644
--- a/libwnck/private.h
+++ b/libwnck/private.h
@@ -106,7 +106,8 @@ SnDisplay* _wnck_screen_get_sn_display (WnckScreen *screen);
WnckScreen* _wnck_screen_get_existing (int number);
-void _wnck_pager_activate_workspace (WnckWorkspace *wspace);
+void _wnck_pager_activate_workspace (WnckWorkspace *wspace,
+ guint32 timestamp);
int _wnck_pager_get_n_workspaces (WnckPager *pager);
const char* _wnck_pager_get_workspace_name (WnckPager *pager,
int i);
diff --git a/libwnck/selector.c b/libwnck/selector.c
index 594602d..796fb02 100644
--- a/libwnck/selector.c
+++ b/libwnck/selector.c
@@ -357,15 +357,8 @@ wnck_selector_active_window_changed (WnckScreen *screen,
static void
wnck_selector_activate_window (WnckWindow *window)
{
- WnckWorkspace *workspace;
-
- workspace = wnck_window_get_workspace (window);
- wnck_workspace_activate (workspace);
-
- if (wnck_window_is_minimized (window))
- wnck_window_unminimize (window);
-
- wnck_window_activate (window);
+ /* We're in an activate callback, so gtk_get_current_time() works... */
+ wnck_window_activate (window, gtk_get_current_event_time ());
}
#define SELECTOR_MAX_WIDTH 50 /* maximum width in characters */
diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c
index 70cd85d..8a85b5f 100644
--- a/libwnck/tasklist.c
+++ b/libwnck/tasklist.c
@@ -116,6 +116,8 @@ struct _WnckTask
guint was_active : 1; /* used to fixup activation behavior */
guint button_activate;
+
+ guint32 dnd_timestamp;
};
struct _WnckTaskClass
@@ -240,7 +242,8 @@ static void wnck_tasklist_connect_window (WnckTasklist *tasklist,
static void wnck_tasklist_change_active_task (WnckTasklist *tasklist,
WnckTask *active_task);
static gboolean wnck_tasklist_change_active_timeout (gpointer data);
-static void wnck_tasklist_activate_task_window (WnckTask *task);
+static void wnck_tasklist_activate_task_window (WnckTask *task,
+ guint32 timestamp);
static void wnck_tasklist_update_icon_geometries (WnckTasklist *tasklist,
GList *visible_tasks);
@@ -1915,11 +1918,15 @@ wnck_task_menu_activated (GtkMenuItem *menu_item,
{
WnckTask *task = WNCK_TASK (data);
- wnck_tasklist_activate_task_window (task);
+ /* This is an "activate" callback function so gtk_get_current_event_time()
+ * will suffice.
+ */
+ wnck_tasklist_activate_task_window (task, gtk_get_current_event_time ());
}
static void
-wnck_tasklist_activate_task_window (WnckTask *task)
+wnck_tasklist_activate_task_window (WnckTask *task,
+ guint32 timestamp)
{
WnckTasklist *tasklist;
WnckWindowState state;
@@ -1940,10 +1947,10 @@ wnck_tasklist_activate_task_window (WnckTask *task)
window_ws = wnck_window_get_workspace (task->window);
if (window_ws &&
active_ws != window_ws &&
- !tasklist->priv->switch_workspace_on_unminimize)
- wnck_workspace_activate (window_ws);
-
- wnck_window_activate_transient (task->window);
+ tasklist->priv->switch_workspace_on_unminimize)
+ wnck_window_move_to_workspace (task->window, active_ws);
+
+ wnck_window_activate_transient (task->window, timestamp);
}
else
{
@@ -1955,14 +1962,8 @@ wnck_tasklist_activate_task_window (WnckTask *task)
}
else
{
- WnckWorkspace *window_ws;
-
- window_ws = wnck_window_get_workspace (task->window);
- if (window_ws)
- wnck_workspace_activate (window_ws);
-
- wnck_window_activate_transient (task->window);
- }
+ wnck_window_activate_transient (task->window, timestamp);
+ }
}
@@ -2002,7 +2003,10 @@ wnck_task_unminimize_all (GtkMenuItem *menu_item,
while (l)
{
WnckTask *child = WNCK_TASK (l->data);
- wnck_window_unminimize (child->window);
+ /* This is inside an activate callback, so gtk_get_current_event_time()
+ * will work.
+ */
+ wnck_window_unminimize (child->window, gtk_get_current_event_time ());
l = l->next;
}
}
@@ -2165,8 +2169,11 @@ wnck_task_button_toggled (GtkButton *button,
case WNCK_TASK_WINDOW:
if (task->window == NULL)
return;
-
- wnck_tasklist_activate_task_window (task);
+
+ /* This should only be called by clicking on the task button, so
+ * gtk_get_current_event_time() should be fine here...
+ */
+ wnck_tasklist_activate_task_window (task, gtk_get_current_event_time ());
break;
case WNCK_TASK_STARTUP_SEQUENCE:
break;
@@ -2510,7 +2517,9 @@ wnck_task_motion_timeout (gpointer data)
task->button_activate = 0;
- wnck_window_activate_transient (task->window);
+ wnck_window_activate_transient (task->window, task->dnd_timestamp);
+
+ task->dnd_timestamp = 0;
return FALSE;
}
@@ -2536,14 +2545,14 @@ wnck_task_drag_motion (GtkWidget *widget,
guint time,
WnckTask *task)
{
+ task->dnd_timestamp = time;
+ if (task->button_activate == 0 && task->type == WNCK_TASK_WINDOW)
+ task->button_activate = g_timeout_add (WNCK_ACTIVATE_TIMEOUT,
+ wnck_task_motion_timeout,
+ task);
+ gdk_drag_status (context,0,time);
- if (task->button_activate == 0 && task->type == WNCK_TASK_WINDOW)
- task->button_activate = g_timeout_add (WNCK_ACTIVATE_TIMEOUT,
- wnck_task_motion_timeout,
- task);
- gdk_drag_status (context,0,time);
-
- return TRUE;
+ return TRUE;
}
static gboolean
diff --git a/libwnck/test-wnck.c b/libwnck/test-wnck.c
index de3dc6f..c974d05 100644
--- a/libwnck/test-wnck.c
+++ b/libwnck/test-wnck.c
@@ -611,7 +611,11 @@ minimized_toggled_callback (GtkCellRendererToggle *cell,
window = get_window (model, &iter);
if (wnck_window_is_minimized (window))
- wnck_window_unminimize (window);
+ /* The toggled callback will only be called in reaction to user
+ * button presses or key presses, so gtk_get_current_event_time()
+ * should be okay here.
+ */
+ wnck_window_unminimize (window, gtk_get_current_event_time ());
else
wnck_window_minimize (window);
@@ -716,7 +720,11 @@ selection_func (GtkTreeSelection *selection,
return TRUE;
else
{
- wnck_window_activate (window);
+ /* This should only be called in reaction to user button
+ * presses or key presses (I hope), so
+ * gtk_get_current_event_time() should be okay here.
+ */
+ wnck_window_activate (window, gtk_get_current_event_time ());
return FALSE;
}
}
diff --git a/libwnck/window-action-menu.c b/libwnck/window-action-menu.c
index 99f95cc..56e0cba 100644
--- a/libwnck/window-action-menu.c
+++ b/libwnck/window-action-menu.c
@@ -111,12 +111,14 @@ item_activated_callback (GtkWidget *menu_item,
switch (action)
{
case CLOSE:
+ /* In an activate callback, so gtk_get_current_event_time() suffices */
wnck_window_close (amd->window,
gtk_get_current_event_time ());
break;
case MINIMIZE:
if (wnck_window_is_minimized (amd->window))
- wnck_window_unminimize (amd->window);
+ wnck_window_unminimize (amd->window,
+ gtk_get_current_event_time ());
else
wnck_window_minimize (amd->window);
break;
diff --git a/libwnck/window.c b/libwnck/window.c
index 381caae..226c2e9 100644
--- a/libwnck/window.c
+++ b/libwnck/window.c
@@ -852,11 +852,12 @@ wnck_window_minimize (WnckWindow *window)
}
void
-wnck_window_unminimize (WnckWindow *window)
+wnck_window_unminimize (WnckWindow *window,
+ guint32 timestamp)
{
g_return_if_fail (WNCK_IS_WINDOW (window));
- wnck_window_activate_transient (window);
+ wnck_window_activate_transient (window, timestamp);
}
void
@@ -1092,12 +1093,14 @@ wnck_window_unpin (WnckWindow *window)
* window manager may choose to raise @window along with focusing it.
**/
void
-wnck_window_activate (WnckWindow *window)
+wnck_window_activate (WnckWindow *window,
+ guint32 timestamp)
{
g_return_if_fail (WNCK_IS_WINDOW (window));
_wnck_activate (WNCK_SCREEN_XSCREEN (window->priv->screen),
- window->priv->xwindow);
+ window->priv->xwindow,
+ timestamp);
}
/**
@@ -1187,7 +1190,8 @@ find_last_transient_for (GList *windows,
*
**/
void
-wnck_window_activate_transient (WnckWindow *window)
+wnck_window_activate_transient (WnckWindow *window,
+ guint32 timestamp)
{
GList *windows;
WnckWindow *transient;
@@ -1215,9 +1219,9 @@ wnck_window_activate_transient (WnckWindow *window)
}
if (transient != NULL)
- wnck_window_activate (transient);
+ wnck_window_activate (transient, timestamp);
else
- wnck_window_activate (window);
+ wnck_window_activate (window, timestamp);
}
/**
diff --git a/libwnck/window.h b/libwnck/window.h
index f01ee95..a3ec07e 100644
--- a/libwnck/window.h
+++ b/libwnck/window.h
@@ -168,9 +168,10 @@ void wnck_window_set_fullscreen (WnckWindow *window,
gboolean fullscreen);
void wnck_window_close (WnckWindow *window,
- guint32 timestamp);
+ guint32 timestamp);
void wnck_window_minimize (WnckWindow *window);
-void wnck_window_unminimize (WnckWindow *window);
+void wnck_window_unminimize (WnckWindow *window,
+ guint32 timestamp);
void wnck_window_maximize (WnckWindow *window);
void wnck_window_unmaximize (WnckWindow *window);
void wnck_window_maximize_horizontally (WnckWindow *window);
@@ -193,10 +194,12 @@ gboolean wnck_window_is_pinned (WnckWindow *window);
void wnck_window_pin (WnckWindow *window);
void wnck_window_unpin (WnckWindow *window);
-void wnck_window_activate (WnckWindow *window);
+void wnck_window_activate (WnckWindow *window,
+ guint32 timestamp);
gboolean wnck_window_is_active (WnckWindow *window);
gboolean wnck_window_is_most_recently_activated (WnckWindow *window);
-void wnck_window_activate_transient (WnckWindow *window);
+void wnck_window_activate_transient (WnckWindow *window,
+ guint32 timestamp);
gboolean wnck_window_transient_is_active (WnckWindow *window);
GdkPixbuf* wnck_window_get_icon (WnckWindow *window);
diff --git a/libwnck/workspace.c b/libwnck/workspace.c
index fe552e7..a95a6a4 100644
--- a/libwnck/workspace.c
+++ b/libwnck/workspace.c
@@ -187,11 +187,14 @@ wnck_workspace_change_name (WnckWorkspace *space,
*
**/
void
-wnck_workspace_activate (WnckWorkspace *space)
+wnck_workspace_activate (WnckWorkspace *space,
+ guint32 timestamp)
{
g_return_if_fail (WNCK_IS_WORKSPACE (space));
- _wnck_activate_workspace (WNCK_SCREEN_XSCREEN (space->priv->screen), space->priv->number);
+ _wnck_activate_workspace (WNCK_SCREEN_XSCREEN (space->priv->screen),
+ space->priv->number,
+ timestamp);
}
WnckWorkspace*
diff --git a/libwnck/workspace.h b/libwnck/workspace.h
index 1d5c0b9..028806a 100644
--- a/libwnck/workspace.h
+++ b/libwnck/workspace.h
@@ -57,7 +57,8 @@ int wnck_workspace_get_number (WnckWorkspace *space);
const char* wnck_workspace_get_name (WnckWorkspace *space);
void wnck_workspace_change_name (WnckWorkspace *space,
const char *name);
-void wnck_workspace_activate (WnckWorkspace *space);
+void wnck_workspace_activate (WnckWorkspace *space,
+ guint32 timestamp);
int wnck_workspace_get_width (WnckWorkspace *space);
int wnck_workspace_get_height (WnckWorkspace *space);
int wnck_workspace_get_viewport_x (WnckWorkspace *space);
diff --git a/libwnck/xutils.c b/libwnck/xutils.c
index fb5146d..cb4c9a8 100644
--- a/libwnck/xutils.c
+++ b/libwnck/xutils.c
@@ -972,13 +972,11 @@ _wnck_change_workspace (Screen *screen,
void
_wnck_activate (Screen *screen,
- Window xwindow)
+ Window xwindow,
+ Time timestamp)
{
XEvent xev;
- Time timestamp;
-
- timestamp = gtk_get_current_event_time();
if (timestamp == 0)
g_warning ("Received a timestamp of 0; window activation may not "
"function properly.\n");
@@ -993,6 +991,8 @@ _wnck_activate (Screen *screen,
xev.xclient.data.l[0] = 2;
xev.xclient.data.l[1] = timestamp;
xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
XSendEvent (gdk_display,
RootWindowOfScreen (screen),
@@ -1003,7 +1003,8 @@ _wnck_activate (Screen *screen,
void
_wnck_activate_workspace (Screen *screen,
- int new_active_space)
+ int new_active_space,
+ Time timestamp)
{
XEvent xev;
@@ -1015,8 +1016,10 @@ _wnck_activate_workspace (Screen *screen,
xev.xclient.message_type = _wnck_atom_get ("_NET_CURRENT_DESKTOP");
xev.xclient.format = 32;
xev.xclient.data.l[0] = new_active_space;
- xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[1] = timestamp;
xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
XSendEvent (gdk_display,
RootWindowOfScreen (screen),
diff --git a/libwnck/xutils.h b/libwnck/xutils.h
index 616163a..f1c6434 100644
--- a/libwnck/xutils.h
+++ b/libwnck/xutils.h
@@ -100,9 +100,11 @@ void _wnck_change_workspace (Screen *screen,
Window xwindow,
int new_space);
void _wnck_activate (Screen *screen,
- Window xwindow);
+ Window xwindow,
+ Time timestamp);
void _wnck_activate_workspace (Screen *screen,
- int new_active_space);
+ int new_active_space,
+ Time timestamp);
void _wnck_change_viewport (Screen *screen,
int x,
int y);