Fix for the "mangles focus window when switching workspaces and using
2003-01-21 Havoc Pennington <hp@pobox.com> Fix for the "mangles focus window when switching workspaces and using mouse focus" bug * src/stack.c (meta_stack_get_default_focus_window_at_point): new function * src/screen.c (meta_screen_focus_mouse_window): new function (meta_screen_focus_default_window): new function * src/workspace.c (meta_workspace_activate): use the new meta_screen_focus_default_window() 2003-01-17 Havoc Pennington <hp@pobox.com> * src/window.c (meta_window_handle_mouse_grab_op_event): fix event compression code to use GDK algorithm suggested by Owen, should be more efficient.
This commit is contained in:
parent
95d747269b
commit
82bd20911c
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
|||||||
|
2003-01-21 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
Fix for the "mangles focus window when switching workspaces
|
||||||
|
and using mouse focus" bug
|
||||||
|
|
||||||
|
* src/stack.c (meta_stack_get_default_focus_window_at_point): new
|
||||||
|
function
|
||||||
|
|
||||||
|
* src/screen.c (meta_screen_focus_mouse_window): new function
|
||||||
|
(meta_screen_focus_default_window): new function
|
||||||
|
|
||||||
|
* src/workspace.c (meta_workspace_activate): use the
|
||||||
|
new meta_screen_focus_default_window()
|
||||||
|
|
||||||
|
2003-01-17 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
* src/window.c (meta_window_handle_mouse_grab_op_event): fix event
|
||||||
|
compression code to use GDK algorithm suggested by Owen, should be
|
||||||
|
more efficient.
|
||||||
|
|
||||||
2003-01-22 Christian Rose <menthos@menthos.com>
|
2003-01-22 Christian Rose <menthos@menthos.com>
|
||||||
|
|
||||||
* configure.in: Added "mn" to ALL_LINGUAS.
|
* configure.in: Added "mn" to ALL_LINGUAS.
|
||||||
|
@ -2798,6 +2798,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
|||||||
display->grab_latest_motion_y = root_y;
|
display->grab_latest_motion_y = root_y;
|
||||||
display->grab_last_moveresize_time.tv_sec = 0;
|
display->grab_last_moveresize_time.tv_sec = 0;
|
||||||
display->grab_last_moveresize_time.tv_usec = 0;
|
display->grab_last_moveresize_time.tv_usec = 0;
|
||||||
|
display->grab_motion_notify_time = 0;
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
display->grab_update_alarm = None;
|
display->grab_update_alarm = None;
|
||||||
#endif
|
#endif
|
||||||
|
@ -245,6 +245,7 @@ struct _MetaDisplay
|
|||||||
MetaRectangle grab_current_window_pos;
|
MetaRectangle grab_current_window_pos;
|
||||||
MetaResizePopup *grab_resize_popup;
|
MetaResizePopup *grab_resize_popup;
|
||||||
GTimeVal grab_last_moveresize_time;
|
GTimeVal grab_last_moveresize_time;
|
||||||
|
Time grab_motion_notify_time;
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
/* alarm monitoring client's _METACITY_UPDATE_COUNTER */
|
/* alarm monitoring client's _METACITY_UPDATE_COUNTER */
|
||||||
XSyncAlarm grab_update_alarm;
|
XSyncAlarm grab_update_alarm;
|
||||||
|
60
src/screen.c
60
src/screen.c
@ -1220,6 +1220,66 @@ meta_screen_focus_top_window (MetaScreen *screen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_screen_focus_mouse_window (MetaScreen *screen,
|
||||||
|
MetaWindow *not_this_one)
|
||||||
|
{
|
||||||
|
MetaWindow *window;
|
||||||
|
Window root_return, child_return;
|
||||||
|
int root_x_return, root_y_return;
|
||||||
|
int win_x_return, win_y_return;
|
||||||
|
unsigned int mask_return;
|
||||||
|
|
||||||
|
if (not_this_one)
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Focusing mouse window excluding %s\n", not_this_one->desc);
|
||||||
|
|
||||||
|
meta_error_trap_push (screen->display);
|
||||||
|
XQueryPointer (screen->display->xdisplay,
|
||||||
|
screen->xroot,
|
||||||
|
&root_return,
|
||||||
|
&child_return,
|
||||||
|
&root_x_return,
|
||||||
|
&root_y_return,
|
||||||
|
&win_x_return,
|
||||||
|
&win_y_return,
|
||||||
|
&mask_return);
|
||||||
|
meta_error_trap_pop (screen->display, TRUE);
|
||||||
|
|
||||||
|
window = meta_stack_get_default_focus_window_at_point (screen->stack,
|
||||||
|
screen->active_workspace,
|
||||||
|
not_this_one,
|
||||||
|
root_x_return,
|
||||||
|
root_y_return);
|
||||||
|
|
||||||
|
/* FIXME I'm a loser on the CurrentTime front */
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Focusing mouse window %s\n", window->desc);
|
||||||
|
|
||||||
|
meta_window_focus (window, meta_display_get_current_time (screen->display));
|
||||||
|
|
||||||
|
/* Also raise the window if in click-to-focus */
|
||||||
|
if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
|
||||||
|
meta_window_raise (window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS, "No mouse window to focus found\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_screen_focus_default_window (MetaScreen *screen,
|
||||||
|
MetaWindow *not_this_one)
|
||||||
|
{
|
||||||
|
if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
|
||||||
|
meta_screen_focus_top_window (screen, not_this_one);
|
||||||
|
else
|
||||||
|
meta_screen_focus_mouse_window (screen, not_this_one);
|
||||||
|
}
|
||||||
|
|
||||||
const MetaXineramaScreenInfo*
|
const MetaXineramaScreenInfo*
|
||||||
meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
|
@ -126,6 +126,10 @@ void meta_screen_ensure_workspace_popup (MetaScreen *screen);
|
|||||||
|
|
||||||
void meta_screen_focus_top_window (MetaScreen *screen,
|
void meta_screen_focus_top_window (MetaScreen *screen,
|
||||||
MetaWindow *not_this_one);
|
MetaWindow *not_this_one);
|
||||||
|
void meta_screen_focus_mouse_window (MetaScreen *screen,
|
||||||
|
MetaWindow *not_this_one);
|
||||||
|
void meta_screen_focus_default_window (MetaScreen *screen,
|
||||||
|
MetaWindow *not_this_one);
|
||||||
|
|
||||||
const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen);
|
const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen);
|
||||||
const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
||||||
|
53
src/stack.c
53
src/stack.c
@ -1301,10 +1301,25 @@ meta_stack_get_below (MetaStack *stack,
|
|||||||
return below;
|
return below;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaWindow*
|
static gboolean
|
||||||
meta_stack_get_default_focus_window (MetaStack *stack,
|
window_contains_point (MetaWindow *window,
|
||||||
|
int root_x,
|
||||||
|
int root_y)
|
||||||
|
{
|
||||||
|
MetaRectangle rect;
|
||||||
|
|
||||||
|
meta_window_get_outer_rect (window, &rect);
|
||||||
|
|
||||||
|
return POINT_IN_RECT (root_x, root_y, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaWindow*
|
||||||
|
get_default_focus_window (MetaStack *stack,
|
||||||
MetaWorkspace *workspace,
|
MetaWorkspace *workspace,
|
||||||
MetaWindow *not_this_one)
|
MetaWindow *not_this_one,
|
||||||
|
gboolean must_be_at_point,
|
||||||
|
int root_x,
|
||||||
|
int root_y)
|
||||||
{
|
{
|
||||||
/* Find the topmost, focusable, mapped, window.
|
/* Find the topmost, focusable, mapped, window.
|
||||||
* not_this_one is being unfocused or going away, so exclude it.
|
* not_this_one is being unfocused or going away, so exclude it.
|
||||||
@ -1353,12 +1368,16 @@ meta_stack_get_default_focus_window (MetaStack *stack,
|
|||||||
{
|
{
|
||||||
if (transient_parent == NULL &&
|
if (transient_parent == NULL &&
|
||||||
not_this_one->xtransient_for != None &&
|
not_this_one->xtransient_for != None &&
|
||||||
not_this_one->xtransient_for == window->xwindow)
|
not_this_one->xtransient_for == window->xwindow &&
|
||||||
|
(!must_be_at_point ||
|
||||||
|
window_contains_point (window, root_x, root_y)))
|
||||||
transient_parent = window;
|
transient_parent = window;
|
||||||
|
|
||||||
if (topmost_in_group == NULL &&
|
if (topmost_in_group == NULL &&
|
||||||
not_this_one_group != NULL &&
|
not_this_one_group != NULL &&
|
||||||
not_this_one_group == meta_window_get_group (window))
|
not_this_one_group == meta_window_get_group (window) &&
|
||||||
|
(!must_be_at_point ||
|
||||||
|
window_contains_point (window, root_x, root_y)))
|
||||||
topmost_in_group = window;
|
topmost_in_group = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,7 +1386,9 @@ meta_stack_get_default_focus_window (MetaStack *stack,
|
|||||||
* focusing dock, even though docks are stacked higher.
|
* focusing dock, even though docks are stacked higher.
|
||||||
*/
|
*/
|
||||||
if (topmost_overall == NULL &&
|
if (topmost_overall == NULL &&
|
||||||
window->type != META_WINDOW_DOCK)
|
window->type != META_WINDOW_DOCK &&
|
||||||
|
(!must_be_at_point ||
|
||||||
|
window_contains_point (window, root_x, root_y)))
|
||||||
topmost_overall = window;
|
topmost_overall = window;
|
||||||
|
|
||||||
/* We could try to bail out early here for efficiency in
|
/* We could try to bail out early here for efficiency in
|
||||||
@ -1388,6 +1409,26 @@ meta_stack_get_default_focus_window (MetaStack *stack,
|
|||||||
return topmost_dock;
|
return topmost_dock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWindow*
|
||||||
|
meta_stack_get_default_focus_window_at_point (MetaStack *stack,
|
||||||
|
MetaWorkspace *workspace,
|
||||||
|
MetaWindow *not_this_one,
|
||||||
|
int root_x,
|
||||||
|
int root_y)
|
||||||
|
{
|
||||||
|
return get_default_focus_window (stack, workspace, not_this_one,
|
||||||
|
TRUE, root_x, root_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWindow*
|
||||||
|
meta_stack_get_default_focus_window (MetaStack *stack,
|
||||||
|
MetaWorkspace *workspace,
|
||||||
|
MetaWindow *not_this_one)
|
||||||
|
{
|
||||||
|
return get_default_focus_window (stack, workspace, not_this_one,
|
||||||
|
FALSE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
GList*
|
GList*
|
||||||
meta_stack_list_windows (MetaStack *stack,
|
meta_stack_list_windows (MetaStack *stack,
|
||||||
MetaWorkspace *workspace)
|
MetaWorkspace *workspace)
|
||||||
|
@ -118,9 +118,16 @@ MetaWindow* meta_stack_get_above (MetaStack *stack,
|
|||||||
MetaWindow* meta_stack_get_below (MetaStack *stack,
|
MetaWindow* meta_stack_get_below (MetaStack *stack,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
gboolean only_within_layer);
|
gboolean only_within_layer);
|
||||||
|
|
||||||
MetaWindow* meta_stack_get_default_focus_window (MetaStack *stack,
|
MetaWindow* meta_stack_get_default_focus_window (MetaStack *stack,
|
||||||
MetaWorkspace *workspace,
|
MetaWorkspace *workspace,
|
||||||
MetaWindow *not_this_one);
|
MetaWindow *not_this_one);
|
||||||
|
MetaWindow* meta_stack_get_default_focus_window_at_point (MetaStack *stack,
|
||||||
|
MetaWorkspace *workspace,
|
||||||
|
MetaWindow *not_this_one,
|
||||||
|
int root_x,
|
||||||
|
int root_y);
|
||||||
|
|
||||||
GList* meta_stack_list_windows (MetaStack *stack,
|
GList* meta_stack_list_windows (MetaStack *stack,
|
||||||
MetaWorkspace *workspace);
|
MetaWorkspace *workspace);
|
||||||
|
|
||||||
|
97
src/window.c
97
src/window.c
@ -6315,61 +6315,78 @@ update_resize (MetaWindow *window,
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
XEvent prev_event;
|
const XEvent *current_event;
|
||||||
gboolean done;
|
|
||||||
int count;
|
int count;
|
||||||
} CompressEventData;
|
Time last_time;
|
||||||
|
} EventScannerData;
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
compress_event_predicate (Display *display,
|
find_last_time_predicate (Display *display,
|
||||||
XEvent *xevent,
|
XEvent *xevent,
|
||||||
XPointer arg)
|
XPointer arg)
|
||||||
{
|
{
|
||||||
CompressEventData *ced = (void*) arg;
|
EventScannerData *esd = (void*) arg;
|
||||||
|
|
||||||
if (ced->done)
|
if (esd->current_event->type == xevent->type &&
|
||||||
return False;
|
esd->current_event->xany.window == xevent->xany.window)
|
||||||
else if (ced->prev_event.type == xevent->type &&
|
|
||||||
ced->prev_event.xany.window == xevent->xany.window)
|
|
||||||
{
|
{
|
||||||
ced->count += 1;
|
esd->count += 1;
|
||||||
return True;
|
esd->last_time = xevent->xmotion.time;
|
||||||
}
|
}
|
||||||
else if (xevent->type != Expose &&
|
|
||||||
xevent->type != ConfigureNotify &&
|
|
||||||
xevent->type != PropertyNotify)
|
|
||||||
{
|
|
||||||
/* Don't compress across most unrelated events, just to be safe */
|
|
||||||
ced->done = TRUE;
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
maybe_replace_with_newer_event (MetaWindow *window,
|
check_use_this_motion_notify (MetaWindow *window,
|
||||||
XEvent *event)
|
XEvent *event)
|
||||||
{
|
{
|
||||||
XEvent new_event;
|
EventScannerData esd;
|
||||||
CompressEventData ced;
|
XEvent useless;
|
||||||
|
|
||||||
/* Chew up all events of the same type on the same window */
|
/* This code is copied from Owen's GDK code. */
|
||||||
|
|
||||||
ced.count = 0;
|
if (window->display->grab_motion_notify_time != 0)
|
||||||
ced.done = FALSE;
|
{
|
||||||
ced.prev_event = *event;
|
/* == is really the right test, but I'm all for paranoia */
|
||||||
while (XCheckIfEvent (window->display->xdisplay,
|
if (window->display->grab_motion_notify_time <=
|
||||||
&new_event,
|
event->xmotion.time)
|
||||||
compress_event_predicate,
|
|
||||||
(void*) &ced.prev_event))
|
|
||||||
ced.prev_event = new_event;
|
|
||||||
|
|
||||||
if (ced.count > 0)
|
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
meta_topic (META_DEBUG_RESIZING,
|
||||||
"Compressed %d motion events\n", ced.count);
|
"Arrived at event with time %lu (waiting for %lu), using it\n",
|
||||||
*event = ced.prev_event;
|
(unsigned long) event->xmotion.time,
|
||||||
|
(unsigned long) window->display->grab_motion_notify_time);
|
||||||
|
window->display->grab_motion_notify_time = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE; /* haven't reached the saved timestamp yet */
|
||||||
|
}
|
||||||
|
|
||||||
|
esd.current_event = event;
|
||||||
|
esd.count = 0;
|
||||||
|
esd.last_time = 0;
|
||||||
|
|
||||||
|
/* "useless" isn't filled in because the predicate never returns True */
|
||||||
|
XCheckIfEvent (window->display->xdisplay,
|
||||||
|
&useless,
|
||||||
|
find_last_time_predicate,
|
||||||
|
(XPointer) &esd);
|
||||||
|
|
||||||
|
if (esd.count > 0)
|
||||||
|
meta_topic (META_DEBUG_RESIZING,
|
||||||
|
"Will skip %d motion events and use the event with time %lu\n",
|
||||||
|
esd.count, (unsigned long) esd.last_time);
|
||||||
|
|
||||||
|
if (esd.last_time == 0)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Save this timestamp, and ignore all motion notify
|
||||||
|
* until we get to the one with this stamp.
|
||||||
|
*/
|
||||||
|
window->display->grab_motion_notify_time = esd.last_time;
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6443,7 +6460,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
if (event->xmotion.root == window->screen->xroot)
|
if (event->xmotion.root == window->screen->xroot)
|
||||||
{
|
{
|
||||||
maybe_replace_with_newer_event (window, event);
|
if (check_use_this_motion_notify (window,
|
||||||
|
event))
|
||||||
update_move (window,
|
update_move (window,
|
||||||
event->xmotion.state,
|
event->xmotion.state,
|
||||||
event->xmotion.x_root,
|
event->xmotion.x_root,
|
||||||
@ -6454,7 +6472,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
if (event->xmotion.root == window->screen->xroot)
|
if (event->xmotion.root == window->screen->xroot)
|
||||||
{
|
{
|
||||||
maybe_replace_with_newer_event (window, event);
|
if (check_use_this_motion_notify (window,
|
||||||
|
event))
|
||||||
update_resize (window,
|
update_resize (window,
|
||||||
event->xmotion.x_root,
|
event->xmotion.x_root,
|
||||||
event->xmotion.y_root);
|
event->xmotion.y_root);
|
||||||
|
@ -216,11 +216,8 @@ meta_workspace_activate (MetaWorkspace *workspace)
|
|||||||
meta_workspace_queue_calc_showing (old);
|
meta_workspace_queue_calc_showing (old);
|
||||||
meta_workspace_queue_calc_showing (workspace);
|
meta_workspace_queue_calc_showing (workspace);
|
||||||
|
|
||||||
/* in mouse focus modes, this will probably get undone by an EnterNotify,
|
meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
|
||||||
* but that's OK
|
meta_screen_focus_default_window (workspace->screen, NULL);
|
||||||
*/
|
|
||||||
meta_topic (META_DEBUG_FOCUS, "Focusing top window on new workspace\n");
|
|
||||||
meta_screen_focus_top_window (workspace->screen, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user