diff options
author | Rob Adams <readams@readams.net> | 2003-12-13 18:28:14 +0000 |
---|---|---|
committer | Rob Adams <readams@src.gnome.org> | 2003-12-13 18:28:14 +0000 |
commit | 7630d22b8d791cf2718e1018b2bffcd672fa3cfa (patch) | |
tree | eddaa83e71e26c7fe0c4b55d4267bc96569eb178 /src | |
parent | a92be6e3196904f222ad9df4893506e5996926ee (diff) | |
download | mutter-7630d22b8d791cf2718e1018b2bffcd672fa3cfa.tar.gz |
Add increased robustness for dealing with all workspaces windows and MRU
2003-12-13 Rob Adams <readams@readams.net>
Add increased robustness for dealing with all workspaces windows
and MRU lists.
Also add very preliminary _NET_WM_USER_TIME
support, limited to simply listening for the property and keeping
an internal variable updated, and also treating some input events
as though they were user time updates.
* src/window.c (meta_window_new_with_attrs): set on_all_workspaces
in all cases _before_ adding to the workspaces, so that windows
initially on all workspaces are added correctly to the MRU lists.
Fix for #120907.
(process_property_notify): add net_wm_user_time support.
* src/workspace.c (meta_workspace_add_window): handle sticky
windows so that we add to add mru lists if needed
(meta_workspace_remove_window): handle sticky windows so that they
are removed from all mru lists if needed.
* src/display.[ch] (meta_display_open): add net_wm_user_time support.
(event_callback): simulate user time update on key and button presses.
* src/screen.c (set_supported_hint): add net_wm_user_time support.
* src/window-props.c (init_net_wm_user_time): new function for
user_time support
(reload_net_wm_user_time): new function for user_time support
(meta_display_init_window_prop_hooks): add hook for user_time
Diffstat (limited to 'src')
-rw-r--r-- | src/display.c | 22 | ||||
-rw-r--r-- | src/display.h | 1 | ||||
-rw-r--r-- | src/screen.c | 3 | ||||
-rw-r--r-- | src/window-props.c | 39 | ||||
-rw-r--r-- | src/window.c | 42 | ||||
-rw-r--r-- | src/window.h | 5 | ||||
-rw-r--r-- | src/workspace.c | 45 |
7 files changed, 136 insertions, 21 deletions
diff --git a/src/display.c b/src/display.c index 4ff003275..b2accdc92 100644 --- a/src/display.c +++ b/src/display.c @@ -274,7 +274,8 @@ meta_display_open (const char *name) "_METACITY_SENTINEL", "_NET_WM_STRUT_PARTIAL", "_NET_WM_ACTION_FULLSCREEN", - "_NET_WM_ACTION_MINIMIZE" + "_NET_WM_ACTION_MINIMIZE", + "_NET_WM_USER_TIME" }; Atom atoms[G_N_ELEMENTS(atom_names)]; @@ -419,6 +420,7 @@ meta_display_open (const char *name) display->atom_net_wm_strut_partial = atoms[80]; display->atom_net_wm_action_fullscreen = atoms[81]; display->atom_net_wm_action_minimize = atoms[82]; + display->atom_net_wm_user_time = atoms[83]; display->prop_hooks = NULL; meta_display_init_window_prop_hooks (display); @@ -1168,7 +1170,8 @@ event_callback (XEvent *event, Window modified; gboolean frame_was_receiver; gboolean filter_out_event; - + Time event_time; + display = data; if (dump_events) @@ -1321,7 +1324,15 @@ event_callback (XEvent *event, meta_compositor_process_event (display->compositor, event, window); - + + if (window && + (event->type == KeyPress || + event->type == ButtonPress) && + (CurrentTime != + (event_time = event_get_time (display, event)))) { + window->net_wm_user_time = event_time; + } + switch (event->type) { case KeyPress: @@ -1867,9 +1878,10 @@ event_callback (XEvent *event, { MetaGroup *group; MetaScreen *screen; - - if (window && !frame_was_receiver) + + if (window && !frame_was_receiver) { meta_window_property_notify (window, event); + } group = meta_display_lookup_group (display, event->xproperty.window); diff --git a/src/display.h b/src/display.h index fc7e631c0..5d2fcc712 100644 --- a/src/display.h +++ b/src/display.h @@ -172,6 +172,7 @@ struct _MetaDisplay Atom atom_gnome_panel_action_run_dialog; Atom atom_metacity_sentinel; Atom atom_net_wm_strut_partial; + Atom atom_net_wm_user_time; /* This is the actual window from focus events, * not the one we last set diff --git a/src/screen.c b/src/screen.c index 2af481fff..825fc114d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -82,7 +82,7 @@ set_wm_check_hint (MetaScreen *screen) static int set_supported_hint (MetaScreen *screen) { -#define N_SUPPORTED 68 +#define N_SUPPORTED 69 Atom atoms[N_SUPPORTED]; atoms[0] = screen->display->atom_net_wm_name; @@ -153,6 +153,7 @@ set_supported_hint (MetaScreen *screen) atoms[65] = screen->display->atom_net_wm_strut_partial; atoms[66] = screen->display->atom_net_wm_action_fullscreen; atoms[67] = screen->display->atom_net_wm_action_minimize; + atoms[68] = screen->display->atom_net_wm_user_time; XChangeProperty (screen->display->xdisplay, screen->xroot, screen->display->atom_net_supported, diff --git a/src/window-props.c b/src/window-props.c index 3dae259a6..5c57ef707 100644 --- a/src/window-props.c +++ b/src/window-props.c @@ -171,6 +171,33 @@ reload_net_wm_pid (MetaWindow *window, } static void +init_net_wm_user_time (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_CARDINAL; + value->atom = display->atom_net_wm_user_time; +} + +static void +reload_net_wm_user_time (MetaWindow *window, + MetaPropValue *value) +{ + if (value->type != META_PROP_VALUE_INVALID) + { + gulong cardinal = (int) value->v.cardinal; + + if (cardinal <= 0) + meta_warning (_("Application set a bogus _NET_WM_USER_TIME %ld\n"), + cardinal); + else + { + window->net_wm_user_time = cardinal; + } + } +} + +static void set_window_title (MetaWindow *window, const char *title) { @@ -814,7 +841,7 @@ reload_wm_hints (MetaWindow *window, -#define N_HOOKS 23 +#define N_HOOKS 24 void meta_display_init_window_prop_hooks (MetaDisplay *display) @@ -844,6 +871,16 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) hooks[i].reload_func = reload_net_wm_pid; ++i; + hooks[i].property = display->atom_net_wm_user_time; + hooks[i].init_func = init_net_wm_user_time; + hooks[i].reload_func = reload_net_wm_user_time; + ++i; + + hooks[i].property = display->atom_net_wm_user_time; + hooks[i].init_func = init_net_wm_user_time; + hooks[i].reload_func = reload_net_wm_user_time; + ++i; + hooks[i].property = display->atom_net_wm_name; hooks[i].init_func = init_net_wm_name; hooks[i].reload_func = reload_net_wm_name; diff --git a/src/window.c b/src/window.c index 7cfaf5e47..a35b501b6 100644 --- a/src/window.c +++ b/src/window.c @@ -582,6 +582,17 @@ meta_window_new_with_attrs (MetaDisplay *display, meta_display_grab_window_buttons (window->display, window->xwindow); meta_display_grab_focus_window_button (window->display, window); + if (window->type == META_WINDOW_DESKTOP || + window->type == META_WINDOW_DOCK) + { + /* Change the default, but don't enforce this if the user + * focuses the dock/desktop and unsticks it using key shortcuts. + * Need to set this before adding to the workspaces so the MRU + * lists will be updated. + */ + window->on_all_workspaces = TRUE; + } + /* For the workspace, first honor hints, * if that fails put transients with parents, * otherwise put window on active space @@ -595,8 +606,11 @@ meta_window_new_with_attrs (MetaDisplay *display, "Window %s is initially on all spaces\n", window->desc); - meta_workspace_add_window (window->screen->active_workspace, window); + /* need to set on_all_workspaces first so that it will be + * added to all the MRU lists + */ window->on_all_workspaces = TRUE; + meta_workspace_add_window (window->screen->active_workspace, window); } else { @@ -636,6 +650,8 @@ meta_window_new_with_attrs (MetaDisplay *display, tmp_list = parent->workspaces; while (tmp_list != NULL) { + /* this will implicitly add to the appropriate MRU lists + */ meta_workspace_add_window (tmp_list->data, window); tmp_list = tmp_list->next; @@ -654,16 +670,6 @@ meta_window_new_with_attrs (MetaDisplay *display, meta_workspace_add_window (space, window); } - if (window->type == META_WINDOW_DESKTOP || - window->type == META_WINDOW_DOCK) - { - /* Change the default, but don't enforce this if - * the user focuses the dock/desktop and unsticks it - * using key shortcuts - */ - window->on_all_workspaces = TRUE; - } - /* for the various on_all_workspaces = TRUE possible above */ meta_window_set_current_workspace_hint (window); @@ -4317,6 +4323,20 @@ process_property_notify (MetaWindow *window, meta_window_reload_property (window, window->display->atom_metacity_update_counter); } + else if (event->atom == window->display->atom_net_wm_user_time) + { + meta_verbose ("Property notify on %s for _NET_WM_USER_TIME\n", window->desc); + + meta_window_reload_property (window, + window->display->atom_net_wm_user_time); + } + else if (event->atom == window->display->atom_net_wm_user_time) + { + meta_verbose ("Property notify on %s for _NET_WM_USER_TIME\n", window->desc); + + meta_window_reload_property (window, + window->display->atom_net_wm_user_time); + } return TRUE; } diff --git a/src/window.h b/src/window.h index 5523af13a..ee8356249 100644 --- a/src/window.h +++ b/src/window.h @@ -242,6 +242,11 @@ struct _MetaWindow /* if TRUE we have a grab on the focus click buttons */ guint have_focus_click_grab : 1; + + /* set to the most recent user-interaction event timestamp that we + * know about for this window + */ + Time net_wm_user_time; #ifdef HAVE_XSYNC /* XSync update counter */ diff --git a/src/workspace.c b/src/workspace.c index e8a820df5..415b04713 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -112,11 +112,30 @@ meta_workspace_add_window (MetaWorkspace *workspace, { g_return_if_fail (!meta_workspace_contains_window (workspace, window)); + /* If the window is on all workspaces, we want to add it to all mru + * lists, otherwise just add it to this workspaces mru list + */ + if (window->on_all_workspaces) + { + if (g_list_length (window->workspaces) == 0) + { + GList* tmp = window->screen->workspaces; + while (tmp) + { + MetaWorkspace* work = (MetaWorkspace*) tmp->data; + if (!g_list_find (work->mru_list, window)) + work->mru_list = g_list_append (work->mru_list, window); + + tmp = tmp->next; + } + } + } + else if (!g_list_find (workspace->mru_list, window)) + workspace->mru_list = g_list_prepend (workspace->mru_list, window); + workspace->windows = g_list_prepend (workspace->windows, window); window->workspaces = g_list_prepend (window->workspaces, workspace); - workspace->mru_list = g_list_append (workspace->mru_list, window); - meta_window_set_current_workspace_hint (window); meta_window_queue_calc_showing (window); @@ -142,7 +161,27 @@ meta_workspace_remove_window (MetaWorkspace *workspace, workspace->windows = g_list_remove (workspace->windows, window); window->workspaces = g_list_remove (window->workspaces, workspace); - workspace->mru_list = g_list_remove (workspace->mru_list, window); + + /* If the window is on all workspaces, we don't want to remove it + * from the MRU list unless this causes it to be removed from all + * workspaces + */ + if (window->on_all_workspaces) + { + if (g_list_length (window->workspaces) == 0) + { + GList* tmp = window->screen->workspaces; + while (tmp) + { + MetaWorkspace* work = (MetaWorkspace*) tmp->data; + work->mru_list = g_list_remove (work->mru_list, window); + + tmp = tmp->next; + } + } + } + else + workspace->mru_list = g_list_remove (workspace->mru_list, window); meta_window_set_current_workspace_hint (window); |