mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
Add support for _NET_WM_USER_TIME
2004-06-17 Elijah Newren <newren@math.utah.edu> Add support for _NET_WM_USER_TIME * src/display.c: (meta_display_open): Add _NET_WM_USER_TIME to atom_names[], (event_callback): Manually set _NET_WM_USER_TIME upon KeyPress (doesn't work since keyboard isn't grabbed) and ButtonPress (does work), this is just a fallback for applications that don't update this themselves. * src/display.h: (struct _MetaDisplay): Add atom_net_wm_user_time field * src/screen.c: (meta_screen_apply_startup_properties): Check for TIMESTAMP provided from startup sequence as well. * src/stack.c: s/meta_window_set_stack_position/meta_window_set_stack_position_no_sync/, (meta_window_set_stack_position): New function which calls the meta_window_set_stack_position_no_sync function followed immediately by calling meta_stack_sync_to_server. * src/window-props.c: (init_net_wm_user_time), (reload_net_wm_user_time): new functions, (reload_wm_hints): also load atom_net_wm_user_time * src/window.c: new XSERVER_TIME_IS_LATER macro (accounts for timestamp wraparound), (meta_window_new_with_attrs): add timestamp attributes, (window_takes_focus_on_map): use TIMESTAMP from startup notification and _NET_WM_USER_TIME to decide whether to focus new windows, (meta_window_show): if app doesn't take focus on map, place it just below the focused window in the stack (process_property_notify): check for changes to _NET_WM_USRE_TIME, (meta_window_stack_just_below): new function * src/window.h: (_MetaWindow struct): new fields for initial_timestamp, initial_timestamp_set, net_wm_user_time_set, and net_wm_user_time, (meta_window_stack_just_below): new function
This commit is contained in:
parent
ef1ecc8128
commit
28a54c6bb4
42
ChangeLog
42
ChangeLog
@ -1,3 +1,45 @@
|
|||||||
|
2004-06-17 Elijah Newren <newren@math.utah.edu>
|
||||||
|
|
||||||
|
Add support for _NET_WM_USER_TIME
|
||||||
|
|
||||||
|
* src/display.c:
|
||||||
|
(meta_display_open): Add _NET_WM_USER_TIME to atom_names[],
|
||||||
|
(event_callback): Manually set _NET_WM_USER_TIME upon KeyPress
|
||||||
|
(doesn't work since keyboard isn't grabbed) and ButtonPress (does
|
||||||
|
work), this is just a fallback for applications that don't update
|
||||||
|
this themselves.
|
||||||
|
|
||||||
|
* src/display.h: (struct _MetaDisplay): Add atom_net_wm_user_time field
|
||||||
|
|
||||||
|
* src/screen.c: (meta_screen_apply_startup_properties): Check for
|
||||||
|
TIMESTAMP provided from startup sequence as well.
|
||||||
|
|
||||||
|
* src/stack.c:
|
||||||
|
s/meta_window_set_stack_position/meta_window_set_stack_position_no_sync/,
|
||||||
|
(meta_window_set_stack_position): New function which calls the
|
||||||
|
meta_window_set_stack_position_no_sync function followed immediately
|
||||||
|
by calling meta_stack_sync_to_server.
|
||||||
|
|
||||||
|
* src/window-props.c:
|
||||||
|
(init_net_wm_user_time), (reload_net_wm_user_time): new functions,
|
||||||
|
(reload_wm_hints): also load atom_net_wm_user_time
|
||||||
|
|
||||||
|
* src/window.c:
|
||||||
|
new XSERVER_TIME_IS_LATER macro (accounts for timestamp wraparound),
|
||||||
|
(meta_window_new_with_attrs): add timestamp attributes,
|
||||||
|
(window_takes_focus_on_map): use TIMESTAMP from startup
|
||||||
|
notification and _NET_WM_USER_TIME to decide whether to focus new
|
||||||
|
windows,
|
||||||
|
(meta_window_show): if app doesn't take focus on map, place it
|
||||||
|
just below the focused window in the stack
|
||||||
|
(process_property_notify): check for changes to _NET_WM_USRE_TIME,
|
||||||
|
(meta_window_stack_just_below): new function
|
||||||
|
|
||||||
|
* src/window.h:
|
||||||
|
(_MetaWindow struct): new fields for initial_timestamp,
|
||||||
|
initial_timestamp_set, net_wm_user_time_set, and net_wm_user_time,
|
||||||
|
(meta_window_stack_just_below): new function
|
||||||
|
|
||||||
2004-06-21 Anders Carlsson <andersca@gnome.org>
|
2004-06-21 Anders Carlsson <andersca@gnome.org>
|
||||||
|
|
||||||
* src/common.h:
|
* src/common.h:
|
||||||
|
@ -281,6 +281,7 @@ meta_display_open (const char *name)
|
|||||||
"_NET_WM_ACTION_MINIMIZE",
|
"_NET_WM_ACTION_MINIMIZE",
|
||||||
"_NET_FRAME_EXTENTS",
|
"_NET_FRAME_EXTENTS",
|
||||||
"_NET_REQUEST_FRAME_EXTENTS",
|
"_NET_REQUEST_FRAME_EXTENTS",
|
||||||
|
"_NET_WM_USER_TIME",
|
||||||
};
|
};
|
||||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
|
|
||||||
@ -427,6 +428,7 @@ meta_display_open (const char *name)
|
|||||||
display->atom_net_wm_action_minimize = atoms[82];
|
display->atom_net_wm_action_minimize = atoms[82];
|
||||||
display->atom_net_frame_extents = atoms[83];
|
display->atom_net_frame_extents = atoms[83];
|
||||||
display->atom_net_request_frame_extents = atoms[84];
|
display->atom_net_request_frame_extents = atoms[84];
|
||||||
|
display->atom_net_wm_user_time = atoms[85];
|
||||||
|
|
||||||
display->prop_hooks = NULL;
|
display->prop_hooks = NULL;
|
||||||
meta_display_init_window_prop_hooks (display);
|
meta_display_init_window_prop_hooks (display);
|
||||||
@ -1177,7 +1179,7 @@ event_callback (XEvent *event,
|
|||||||
Window modified;
|
Window modified;
|
||||||
gboolean frame_was_receiver;
|
gboolean frame_was_receiver;
|
||||||
gboolean filter_out_event;
|
gboolean filter_out_event;
|
||||||
|
|
||||||
display = data;
|
display = data;
|
||||||
|
|
||||||
if (dump_events)
|
if (dump_events)
|
||||||
@ -1326,6 +1328,16 @@ event_callback (XEvent *event,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SHAPE */
|
#endif /* HAVE_SHAPE */
|
||||||
|
|
||||||
|
if (window && ((event->type == KeyPress) || (event->type == ButtonPress)))
|
||||||
|
{
|
||||||
|
g_assert (CurrentTime != display->current_time);
|
||||||
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||||
|
"Metacity set %s's net_wm_user_time to %d.\n",
|
||||||
|
window->desc, display->current_time);
|
||||||
|
window->net_wm_user_time_set = TRUE;
|
||||||
|
window->net_wm_user_time = display->current_time;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
|
@ -175,6 +175,7 @@ struct _MetaDisplay
|
|||||||
Atom atom_net_wm_strut_partial;
|
Atom atom_net_wm_strut_partial;
|
||||||
Atom atom_net_frame_extents;
|
Atom atom_net_frame_extents;
|
||||||
Atom atom_net_request_frame_extents;
|
Atom atom_net_request_frame_extents;
|
||||||
|
Atom atom_net_wm_user_time;
|
||||||
|
|
||||||
/* This is the actual window from focus events,
|
/* This is the actual window from focus events,
|
||||||
* not the one we last set
|
* not the one we last set
|
||||||
|
12
src/screen.c
12
src/screen.c
@ -2481,6 +2481,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
|||||||
if (sequence != NULL)
|
if (sequence != NULL)
|
||||||
{
|
{
|
||||||
int space;
|
int space;
|
||||||
|
Time timestamp;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STARTUP,
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
"Found startup sequence for window %s ID \"%s\"\n",
|
"Found startup sequence for window %s ID \"%s\"\n",
|
||||||
@ -2500,6 +2501,17 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!window->initial_timestamp_set)
|
||||||
|
{
|
||||||
|
timestamp = sn_startup_sequence_get_timestamp (sequence);
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"Setting initial window timestamp to %lu based on startup info\n",
|
||||||
|
timestamp);
|
||||||
|
|
||||||
|
window->initial_timestamp_set = TRUE;
|
||||||
|
window->initial_timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
26
src/stack.c
26
src/stack.c
@ -47,6 +47,8 @@
|
|||||||
#define WINDOW_IN_STACK(w) (w->stack_position >= 0)
|
#define WINDOW_IN_STACK(w) (w->stack_position >= 0)
|
||||||
|
|
||||||
static void meta_stack_sync_to_server (MetaStack *stack);
|
static void meta_stack_sync_to_server (MetaStack *stack);
|
||||||
|
static void meta_window_set_stack_position_no_sync (MetaWindow *window,
|
||||||
|
int position);
|
||||||
|
|
||||||
MetaStack*
|
MetaStack*
|
||||||
meta_stack_new (MetaScreen *screen)
|
meta_stack_new (MetaScreen *screen)
|
||||||
@ -122,8 +124,8 @@ meta_stack_remove (MetaStack *stack,
|
|||||||
/* Set window to top position, so removing it will not leave gaps
|
/* Set window to top position, so removing it will not leave gaps
|
||||||
* in the set of positions
|
* in the set of positions
|
||||||
*/
|
*/
|
||||||
meta_window_set_stack_position (window,
|
meta_window_set_stack_position_no_sync (window,
|
||||||
stack->n_positions - 1);
|
stack->n_positions - 1);
|
||||||
window->stack_position = -1;
|
window->stack_position = -1;
|
||||||
stack->n_positions -= 1;
|
stack->n_positions -= 1;
|
||||||
|
|
||||||
@ -162,8 +164,8 @@ void
|
|||||||
meta_stack_raise (MetaStack *stack,
|
meta_stack_raise (MetaStack *stack,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
meta_window_set_stack_position (window,
|
meta_window_set_stack_position_no_sync (window,
|
||||||
stack->n_positions - 1);
|
stack->n_positions - 1);
|
||||||
|
|
||||||
meta_stack_sync_to_server (stack);
|
meta_stack_sync_to_server (stack);
|
||||||
}
|
}
|
||||||
@ -172,7 +174,7 @@ void
|
|||||||
meta_stack_lower (MetaStack *stack,
|
meta_stack_lower (MetaStack *stack,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
meta_window_set_stack_position (window, 0);
|
meta_window_set_stack_position_no_sync (window, 0);
|
||||||
|
|
||||||
meta_stack_sync_to_server (stack);
|
meta_stack_sync_to_server (stack);
|
||||||
}
|
}
|
||||||
@ -669,7 +671,7 @@ ensure_above (MetaWindow *above,
|
|||||||
if (above->stack_position < below->stack_position)
|
if (above->stack_position < below->stack_position)
|
||||||
{
|
{
|
||||||
/* move above to below->stack_position bumping below down the stack */
|
/* move above to below->stack_position bumping below down the stack */
|
||||||
meta_window_set_stack_position (above, below->stack_position);
|
meta_window_set_stack_position_no_sync (above, below->stack_position);
|
||||||
g_assert (below->stack_position + 1 == above->stack_position);
|
g_assert (below->stack_position + 1 == above->stack_position);
|
||||||
}
|
}
|
||||||
meta_topic (META_DEBUG_STACK, "%s above at %d > %s below at %d\n",
|
meta_topic (META_DEBUG_STACK, "%s above at %d > %s below at %d\n",
|
||||||
@ -1465,8 +1467,8 @@ meta_stack_windows_cmp (MetaStack *stack,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_set_stack_position (MetaWindow *window,
|
meta_window_set_stack_position_no_sync (MetaWindow *window,
|
||||||
int position)
|
int position)
|
||||||
{
|
{
|
||||||
int low, high, delta;
|
int low, high, delta;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
@ -1517,3 +1519,11 @@ meta_window_set_stack_position (MetaWindow *window,
|
|||||||
"Window %s had stack_position set to %d\n",
|
"Window %s had stack_position set to %d\n",
|
||||||
window->desc, window->stack_position);
|
window->desc, window->stack_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_set_stack_position (MetaWindow *window,
|
||||||
|
int position)
|
||||||
|
{
|
||||||
|
meta_window_set_stack_position_no_sync (window, position);
|
||||||
|
meta_stack_sync_to_server (window->screen->stack);
|
||||||
|
}
|
||||||
|
@ -141,7 +141,3 @@ void meta_window_set_stack_position (MetaWindow *window,
|
|||||||
int position);
|
int position);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,6 +170,31 @@ 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 = value->v.cardinal;
|
||||||
|
|
||||||
|
window->net_wm_user_time_set = TRUE;
|
||||||
|
window->net_wm_user_time = cardinal;
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"Window %s has _NET_WM_USER_TIME of %lu\n",
|
||||||
|
window->desc, window->net_wm_user_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_window_title (MetaWindow *window,
|
set_window_title (MetaWindow *window,
|
||||||
const char *title)
|
const char *title)
|
||||||
@ -814,7 +839,7 @@ reload_wm_hints (MetaWindow *window,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define N_HOOKS 23
|
#define N_HOOKS 24
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_display_init_window_prop_hooks (MetaDisplay *display)
|
meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||||
@ -844,6 +869,11 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
|||||||
hooks[i].reload_func = reload_net_wm_pid;
|
hooks[i].reload_func = reload_net_wm_pid;
|
||||||
++i;
|
++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].property = display->atom_net_wm_name;
|
||||||
hooks[i].init_func = init_net_wm_name;
|
hooks[i].init_func = init_net_wm_name;
|
||||||
hooks[i].reload_func = reload_net_wm_name;
|
hooks[i].reload_func = reload_net_wm_name;
|
||||||
|
157
src/window.c
157
src/window.c
@ -47,6 +47,14 @@
|
|||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Xserver time can wraparound, thus comparing two timestamps needs to take
|
||||||
|
* this into account. Here's a little macro to help out.
|
||||||
|
*/
|
||||||
|
#define XSERVER_TIME_IS_LATER(time1, time2) \
|
||||||
|
( ((time1 >= time2) && (time1 - time2 < G_MAXULONG / 2)) || \
|
||||||
|
((time1 < time2) && (time2 - time1 > G_MAXULONG / 2)) \
|
||||||
|
)
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||||
@ -216,7 +224,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
MetaWorkspace *space;
|
MetaWorkspace *space;
|
||||||
gulong existing_wm_state;
|
gulong existing_wm_state;
|
||||||
gulong event_mask;
|
gulong event_mask;
|
||||||
#define N_INITIAL_PROPS 12
|
#define N_INITIAL_PROPS 13
|
||||||
Atom initial_props[N_INITIAL_PROPS];
|
Atom initial_props[N_INITIAL_PROPS];
|
||||||
int i;
|
int i;
|
||||||
gboolean has_shape;
|
gboolean has_shape;
|
||||||
@ -446,6 +454,8 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
window->all_keys_grabbed = FALSE;
|
window->all_keys_grabbed = FALSE;
|
||||||
window->withdrawn = FALSE;
|
window->withdrawn = FALSE;
|
||||||
window->initial_workspace_set = FALSE;
|
window->initial_workspace_set = FALSE;
|
||||||
|
window->initial_timestamp_set = FALSE;
|
||||||
|
window->net_wm_user_time_set = FALSE;
|
||||||
window->calc_placement = FALSE;
|
window->calc_placement = FALSE;
|
||||||
window->shaken_loose = FALSE;
|
window->shaken_loose = FALSE;
|
||||||
window->have_focus_click_grab = FALSE;
|
window->have_focus_click_grab = FALSE;
|
||||||
@ -509,6 +519,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
window->layer = META_LAYER_LAST; /* invalid value */
|
window->layer = META_LAYER_LAST; /* invalid value */
|
||||||
window->stack_position = -1;
|
window->stack_position = -1;
|
||||||
window->initial_workspace = 0; /* not used */
|
window->initial_workspace = 0; /* not used */
|
||||||
|
window->initial_timestamp = 0; /* not used */
|
||||||
|
|
||||||
meta_display_register_x_window (display, &window->xwindow, window);
|
meta_display_register_x_window (display, &window->xwindow, window);
|
||||||
|
|
||||||
@ -536,6 +547,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
initial_props[i++] = XA_WM_NORMAL_HINTS;
|
initial_props[i++] = XA_WM_NORMAL_HINTS;
|
||||||
initial_props[i++] = display->atom_wm_protocols;
|
initial_props[i++] = display->atom_wm_protocols;
|
||||||
initial_props[i++] = XA_WM_HINTS;
|
initial_props[i++] = XA_WM_HINTS;
|
||||||
|
initial_props[i++] = display->atom_net_wm_user_time;
|
||||||
g_assert (N_INITIAL_PROPS == i);
|
g_assert (N_INITIAL_PROPS == i);
|
||||||
|
|
||||||
meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
|
meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
|
||||||
@ -1555,6 +1567,8 @@ meta_window_queue_calc_showing (MetaWindow *window)
|
|||||||
static gboolean
|
static gboolean
|
||||||
window_takes_focus_on_map (MetaWindow *window)
|
window_takes_focus_on_map (MetaWindow *window)
|
||||||
{
|
{
|
||||||
|
Time compare;
|
||||||
|
|
||||||
/* don't initially focus windows that are intended to not accept
|
/* don't initially focus windows that are intended to not accept
|
||||||
* focus
|
* focus
|
||||||
*/
|
*/
|
||||||
@ -1572,41 +1586,80 @@ window_takes_focus_on_map (MetaWindow *window)
|
|||||||
/* don't focus these */
|
/* don't focus these */
|
||||||
break;
|
break;
|
||||||
case META_WINDOW_NORMAL:
|
case META_WINDOW_NORMAL:
|
||||||
|
|
||||||
/* Always focus new windows */
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Old Windows-XP style rule for reference */
|
|
||||||
/* Focus only if the current focus is on a desktop element
|
|
||||||
* or nonexistent.
|
|
||||||
*
|
|
||||||
* (using display->focus_window is a bit of a race condition,
|
|
||||||
* but I have no idea how to avoid it)
|
|
||||||
*/
|
|
||||||
if (window->display->focus_window == NULL ||
|
|
||||||
(window->display->focus_window &&
|
|
||||||
(window->display->focus_window->type == META_WINDOW_DOCK ||
|
|
||||||
window->display->focus_window->type == META_WINDOW_DESKTOP)))
|
|
||||||
return TRUE;
|
|
||||||
break;
|
|
||||||
case META_WINDOW_DIALOG:
|
case META_WINDOW_DIALOG:
|
||||||
case META_WINDOW_MODAL_DIALOG:
|
case META_WINDOW_MODAL_DIALOG:
|
||||||
|
|
||||||
/* Always focus */
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
return TRUE;
|
"COMPARISON:\n"
|
||||||
|
" net_wm_user_time_set : %d\n"
|
||||||
|
" net_wm_user_time : %lu\n"
|
||||||
|
" initial_timestamp_set: %d\n"
|
||||||
|
" initial_timestamp : %lu\n",
|
||||||
|
window->net_wm_user_time_set,
|
||||||
|
window->net_wm_user_time,
|
||||||
|
window->initial_timestamp_set,
|
||||||
|
window->initial_timestamp);
|
||||||
|
if (window->display->focus_window != NULL) {
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"COMPARISON (continued):\n"
|
||||||
|
" focus_window : %s\n"
|
||||||
|
" fw->net_wm_user_time : %lu\n",
|
||||||
|
window->display->focus_window->desc,
|
||||||
|
window->display->focus_window->net_wm_user_time);
|
||||||
|
}
|
||||||
|
|
||||||
/* Old Windows-XP style rule for reference */
|
/* We expect the most common case for not focusing a new window
|
||||||
/* Focus only if the transient parent has focus */
|
* to be when a hint to not focus it has been set. Since we can
|
||||||
/* (using display->focus_window is a bit of a race condition,
|
* deal with that case rapidly, we use special case it--this is
|
||||||
* but I have no idea how to avoid it)
|
* merely a preliminary optimization. :)
|
||||||
*/
|
*/
|
||||||
if (window->display->focus_window == NULL ||
|
if ( ((window->net_wm_user_time_set == TRUE) &&
|
||||||
(window->display->focus_window &&
|
(window->net_wm_user_time == 0))
|
||||||
meta_window_is_ancestor_of_transient (window->display->focus_window,
|
||
|
||||||
window)) ||
|
((window->initial_timestamp_set == TRUE) &&
|
||||||
(window->display->focus_window->type == META_WINDOW_DOCK ||
|
(window->initial_timestamp == 0)))
|
||||||
window->display->focus_window->type == META_WINDOW_DESKTOP))
|
{
|
||||||
return TRUE;
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"window %s explicitly requested no focus\n",
|
||||||
|
window->desc);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(window->net_wm_user_time_set) && !(window->initial_timestamp_set))
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"no information about window %s found\n",
|
||||||
|
window->desc);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To determine the "launch" time of an application,
|
||||||
|
* startup-notification can set the TIMESTAMP and the
|
||||||
|
* application (usually via its toolkit such as gtk or qt) can
|
||||||
|
* set the _NET_WM_USER_TIME. If both are set, then it means
|
||||||
|
* the user has interacted with the application since it
|
||||||
|
* launched, and _NET_WM_USER_TIME is the value that should be
|
||||||
|
* used in the comparison.
|
||||||
|
*/
|
||||||
|
compare = window->initial_timestamp_set ? window->initial_timestamp : 0;
|
||||||
|
compare = window->net_wm_user_time_set ? window->net_wm_user_time : compare;
|
||||||
|
|
||||||
|
if ((window->display->focus_window == NULL) ||
|
||||||
|
(XSERVER_TIME_IS_LATER (compare, window->display->focus_window->net_wm_user_time)))
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"new window %s with no intervening events\n",
|
||||||
|
window->desc);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"window %s focus prevented by other activity; %lu is before %lu\n",
|
||||||
|
window->desc, compare, window->display->focus_window->net_wm_user_time);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1618,13 +1671,20 @@ meta_window_show (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
gboolean did_placement;
|
gboolean did_placement;
|
||||||
gboolean did_show;
|
gboolean did_show;
|
||||||
|
gboolean takes_focus_on_map;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||||
"Showing window %s, shaded: %d iconic: %d placed: %d\n",
|
"Showing window %s, shaded: %d iconic: %d placed: %d\n",
|
||||||
window->desc, window->shaded, window->iconic, window->placed);
|
window->desc, window->shaded, window->iconic, window->placed);
|
||||||
|
|
||||||
did_show = FALSE;
|
did_show = FALSE;
|
||||||
did_placement = FALSE;
|
did_placement = FALSE;
|
||||||
|
takes_focus_on_map = window_takes_focus_on_map (window);
|
||||||
|
|
||||||
|
if ( (!takes_focus_on_map) && (window->display->focus_window != NULL) )
|
||||||
|
meta_window_stack_just_below (window,
|
||||||
|
window->display->focus_window);
|
||||||
|
|
||||||
if (!window->placed)
|
if (!window->placed)
|
||||||
{
|
{
|
||||||
/* We have to recalc the placement here since other windows may
|
/* We have to recalc the placement here since other windows may
|
||||||
@ -1721,7 +1781,7 @@ meta_window_show (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window_takes_focus_on_map (window))
|
if (takes_focus_on_map)
|
||||||
{
|
{
|
||||||
meta_window_focus (window,
|
meta_window_focus (window,
|
||||||
meta_display_get_current_time (window->display));
|
meta_display_get_current_time (window->display));
|
||||||
@ -4418,6 +4478,13 @@ process_property_notify (MetaWindow *window,
|
|||||||
meta_window_reload_property (window,
|
meta_window_reload_property (window,
|
||||||
window->display->atom_net_wm_sync_request_counter);
|
window->display->atom_net_wm_sync_request_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);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -7056,3 +7123,27 @@ meta_window_update_layer (MetaWindow *window)
|
|||||||
meta_stack_update_layer (window->screen->stack, window);
|
meta_stack_update_layer (window->screen->stack, window);
|
||||||
meta_stack_thaw (window->screen->stack);
|
meta_stack_thaw (window->screen->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_stack_just_below (MetaWindow *window,
|
||||||
|
MetaWindow *below_this_one)
|
||||||
|
{
|
||||||
|
g_return_if_fail (window != NULL);
|
||||||
|
g_return_if_fail (below_this_one != NULL);
|
||||||
|
|
||||||
|
if (window->stack_position > below_this_one->stack_position)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_STACK,
|
||||||
|
"Setting stack position of window %s to %d (making it below window %s).\n",
|
||||||
|
window->desc,
|
||||||
|
below_this_one->stack_position - 1,
|
||||||
|
below_this_one->desc);
|
||||||
|
meta_window_set_stack_position (window, below_this_one->stack_position - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_STACK,
|
||||||
|
"Window %s was already below window %s.\n",
|
||||||
|
window->desc, below_this_one->desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
20
src/window.h
20
src/window.h
@ -103,6 +103,9 @@ struct _MetaWindow
|
|||||||
/* Initial workspace property */
|
/* Initial workspace property */
|
||||||
int initial_workspace;
|
int initial_workspace;
|
||||||
|
|
||||||
|
/* Initial timestamp property */
|
||||||
|
Time initial_timestamp;
|
||||||
|
|
||||||
/* Whether we're maximized */
|
/* Whether we're maximized */
|
||||||
guint maximized : 1;
|
guint maximized : 1;
|
||||||
guint maximize_after_placement : 1;
|
guint maximize_after_placement : 1;
|
||||||
@ -139,6 +142,12 @@ struct _MetaWindow
|
|||||||
/* whether an initial workspace was explicitly set */
|
/* whether an initial workspace was explicitly set */
|
||||||
guint initial_workspace_set : 1;
|
guint initial_workspace_set : 1;
|
||||||
|
|
||||||
|
/* whether an initial timestamp was explicitly set */
|
||||||
|
guint initial_timestamp_set : 1;
|
||||||
|
|
||||||
|
/* whether net_wm_user_time has been set yet */
|
||||||
|
guint net_wm_user_time_set : 1;
|
||||||
|
|
||||||
/* These are the flags from WM_PROTOCOLS */
|
/* These are the flags from WM_PROTOCOLS */
|
||||||
guint take_focus : 1;
|
guint take_focus : 1;
|
||||||
guint delete_window : 1;
|
guint delete_window : 1;
|
||||||
@ -259,6 +268,10 @@ struct _MetaWindow
|
|||||||
* is withdrawing the window.
|
* is withdrawing the window.
|
||||||
*/
|
*/
|
||||||
int unmaps_pending;
|
int unmaps_pending;
|
||||||
|
|
||||||
|
/* set to the most recent user-interaction event timestamp that we
|
||||||
|
know about for this window */
|
||||||
|
Time net_wm_user_time;
|
||||||
|
|
||||||
/* The size we set the window to last (i.e. what we believe
|
/* The size we set the window to last (i.e. what we believe
|
||||||
* to be its actual size on the server). The x, y are
|
* to be its actual size on the server). The x, y are
|
||||||
@ -501,8 +514,7 @@ void meta_window_recalc_features (MetaWindow *window);
|
|||||||
|
|
||||||
void meta_window_queue_update_icon (MetaWindow *window);
|
void meta_window_queue_update_icon (MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_window_stack_just_below (MetaWindow *window,
|
||||||
|
MetaWindow *below_this_one);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user