Compare commits
3 Commits
3.18.2
...
wip/cullin
Author | SHA1 | Date | |
---|---|---|---|
![]() |
48b74b86ec | ||
![]() |
91c2225ecd | ||
![]() |
2aa24f2da8 |
@@ -303,7 +303,7 @@ meta_core_user_focus (Display *xdisplay,
|
|||||||
{
|
{
|
||||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -482,7 +482,7 @@ meta_core_show_window_menu (Display *xdisplay,
|
|||||||
|
|
||||||
if (meta_prefs_get_raise_on_click ())
|
if (meta_prefs_get_raise_on_click ())
|
||||||
meta_window_raise (window);
|
meta_window_raise (window);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
|
|
||||||
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
||||||
}
|
}
|
||||||
|
@@ -117,15 +117,6 @@ typedef struct
|
|||||||
guint ping_timeout_id;
|
guint ping_timeout_id;
|
||||||
} MetaPingData;
|
} MetaPingData;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MetaDisplay *display;
|
|
||||||
MetaWindow *window;
|
|
||||||
int pointer_x;
|
|
||||||
int pointer_y;
|
|
||||||
} MetaFocusData;
|
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
|
G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
|
||||||
|
|
||||||
/* Signals */
|
/* Signals */
|
||||||
@@ -1561,21 +1552,6 @@ crossing_serial_is_ignored (MetaDisplay *display,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
reset_ignored_crossing_serials (MetaDisplay *display)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (i < N_IGNORED_CROSSING_SERIALS)
|
|
||||||
{
|
|
||||||
display->ignored_crossing_serials[i] = 0;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
display->ungrab_should_not_cause_focus_window = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
window_raise_with_delay_callback (void *data)
|
window_raise_with_delay_callback (void *data)
|
||||||
{
|
{
|
||||||
@@ -1616,110 +1592,6 @@ window_raise_with_delay_callback (void *data)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
meta_display_mouse_mode_focus (MetaDisplay *display,
|
|
||||||
MetaWindow *window,
|
|
||||||
guint32 timestamp)
|
|
||||||
{
|
|
||||||
if (window->type != META_WINDOW_DESKTOP)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
|
||||||
"Focusing %s at time %u.\n", window->desc, timestamp);
|
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
|
||||||
|
|
||||||
if (meta_prefs_get_auto_raise ())
|
|
||||||
meta_display_queue_autoraise_callback (display, window);
|
|
||||||
else
|
|
||||||
meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* In mouse focus mode, we defocus when the mouse *enters*
|
|
||||||
* the DESKTOP window, instead of defocusing on LeaveNotify.
|
|
||||||
* This is because having the mouse enter override-redirect
|
|
||||||
* child windows unfortunately causes LeaveNotify events that
|
|
||||||
* we can't distinguish from the mouse actually leaving the
|
|
||||||
* toplevel window as we expect. But, since we filter out
|
|
||||||
* EnterNotify events on override-redirect windows, this
|
|
||||||
* alternative mechanism works great.
|
|
||||||
*/
|
|
||||||
if (meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE &&
|
|
||||||
display->focus_window != NULL)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
|
||||||
"Unsetting focus from %s due to mouse entering "
|
|
||||||
"the DESKTOP window\n",
|
|
||||||
display->focus_window->desc);
|
|
||||||
meta_display_focus_the_no_focus_window (display,
|
|
||||||
window->screen,
|
|
||||||
timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
window_focus_on_pointer_rest_callback (gpointer data)
|
|
||||||
{
|
|
||||||
MetaFocusData *focus_data;
|
|
||||||
MetaDisplay *display;
|
|
||||||
MetaScreen *screen;
|
|
||||||
MetaWindow *window;
|
|
||||||
Window root, child;
|
|
||||||
double root_x, root_y, x, y;
|
|
||||||
guint32 timestamp;
|
|
||||||
XIButtonState buttons;
|
|
||||||
XIModifierState mods;
|
|
||||||
XIGroupState group;
|
|
||||||
|
|
||||||
focus_data = data;
|
|
||||||
display = focus_data->display;
|
|
||||||
screen = focus_data->window->screen;
|
|
||||||
|
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
meta_error_trap_push (display);
|
|
||||||
XIQueryPointer (display->xdisplay,
|
|
||||||
META_VIRTUAL_CORE_POINTER_ID,
|
|
||||||
screen->xroot,
|
|
||||||
&root, &child,
|
|
||||||
&root_x, &root_y, &x, &y,
|
|
||||||
&buttons, &mods, &group);
|
|
||||||
meta_error_trap_pop (display);
|
|
||||||
free (buttons.mask);
|
|
||||||
|
|
||||||
if (root_x != focus_data->pointer_x ||
|
|
||||||
root_y != focus_data->pointer_y)
|
|
||||||
{
|
|
||||||
focus_data->pointer_x = root_x;
|
|
||||||
focus_data->pointer_y = root_y;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Explicitly check for the overlay window, as get_focus_window_at_point()
|
|
||||||
* may return windows that extend underneath the chrome (like
|
|
||||||
* override-redirect or DESKTOP windows)
|
|
||||||
*/
|
|
||||||
if (child == meta_get_overlay_window (screen))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
window =
|
|
||||||
meta_stack_get_default_focus_window_at_point (screen->stack,
|
|
||||||
screen->active_workspace,
|
|
||||||
None, root_x, root_y);
|
|
||||||
|
|
||||||
if (window == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
timestamp = meta_display_get_current_time_roundtrip (display);
|
|
||||||
meta_display_mouse_mode_focus (display, window, timestamp);
|
|
||||||
|
|
||||||
out:
|
|
||||||
display->focus_timeout_id = 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_display_queue_autoraise_callback (MetaDisplay *display,
|
meta_display_queue_autoraise_callback (MetaDisplay *display,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
@@ -1740,37 +1612,6 @@ meta_display_queue_autoraise_callback (MetaDisplay *display,
|
|||||||
display->autoraise_window = window;
|
display->autoraise_window = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The interval, in milliseconds, we use in focus-follows-mouse
|
|
||||||
* mode to check whether the pointer has stopped moving after a
|
|
||||||
* crossing event.
|
|
||||||
*/
|
|
||||||
#define FOCUS_TIMEOUT_DELAY 25
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_display_queue_focus_callback (MetaDisplay *display,
|
|
||||||
MetaWindow *window,
|
|
||||||
int pointer_x,
|
|
||||||
int pointer_y)
|
|
||||||
{
|
|
||||||
MetaFocusData *focus_data;
|
|
||||||
|
|
||||||
focus_data = g_new (MetaFocusData, 1);
|
|
||||||
focus_data->display = display;
|
|
||||||
focus_data->window = window;
|
|
||||||
focus_data->pointer_x = pointer_x;
|
|
||||||
focus_data->pointer_y = pointer_y;
|
|
||||||
|
|
||||||
if (display->focus_timeout_id != 0)
|
|
||||||
g_source_remove (display->focus_timeout_id);
|
|
||||||
|
|
||||||
display->focus_timeout_id =
|
|
||||||
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
|
||||||
FOCUS_TIMEOUT_DELAY,
|
|
||||||
window_focus_on_pointer_rest_callback,
|
|
||||||
focus_data,
|
|
||||||
g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void
|
static void
|
||||||
handle_net_restack_window (MetaDisplay* display,
|
handle_net_restack_window (MetaDisplay* display,
|
||||||
@@ -2403,7 +2244,7 @@ event_callback (XEvent *event,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing %s due to unmodified button %u press (display.c)\n",
|
"Focusing %s due to unmodified button %u press (display.c)\n",
|
||||||
window->desc, device_event->detail);
|
window->desc, device_event->detail);
|
||||||
meta_window_focus (window, device_event->time);
|
meta_window_focus_implicitly (window, device_event->time);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* However, do allow terminals to lose focus due to new
|
/* However, do allow terminals to lose focus due to new
|
||||||
@@ -2552,36 +2393,10 @@ event_callback (XEvent *event,
|
|||||||
enter_event->detail != XINotifyInferior &&
|
enter_event->detail != XINotifyInferior &&
|
||||||
meta_display_focus_sentinel_clear (display))
|
meta_display_focus_sentinel_clear (display))
|
||||||
{
|
{
|
||||||
switch (meta_prefs_get_focus_mode ())
|
meta_window_handle_enter (window,
|
||||||
{
|
enter_event->time,
|
||||||
case G_DESKTOP_FOCUS_MODE_SLOPPY:
|
|
||||||
case G_DESKTOP_FOCUS_MODE_MOUSE:
|
|
||||||
display->mouse_mode = TRUE;
|
|
||||||
if (window->type != META_WINDOW_DOCK)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
|
||||||
"Queuing a focus change for %s due to "
|
|
||||||
"enter notify with serial %lu at time %lu, "
|
|
||||||
"and setting display->mouse_mode to TRUE.\n",
|
|
||||||
window->desc,
|
|
||||||
event->xany.serial,
|
|
||||||
enter_event->time);
|
|
||||||
|
|
||||||
if (meta_prefs_get_focus_change_on_pointer_rest())
|
|
||||||
meta_display_queue_focus_callback (display, window,
|
|
||||||
enter_event->root_x,
|
enter_event->root_x,
|
||||||
enter_event->root_y);
|
enter_event->root_y);
|
||||||
else
|
|
||||||
meta_display_mouse_mode_focus (display, window,
|
|
||||||
enter_event->time);
|
|
||||||
|
|
||||||
/* stop ignoring stuff */
|
|
||||||
reset_ignored_crossing_serials (display);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case G_DESKTOP_FOCUS_MODE_CLICK:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->type == META_WINDOW_DOCK)
|
if (window->type == META_WINDOW_DOCK)
|
||||||
meta_window_raise (window);
|
meta_window_raise (window);
|
||||||
|
@@ -1578,7 +1578,7 @@ meta_window_grab_all_keys (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing %s because we're grabbing all its keys\n",
|
"Focusing %s because we're grabbing all its keys\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
|
|
||||||
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
||||||
|
|
||||||
|
@@ -2984,7 +2984,7 @@ meta_screen_show_desktop (MetaScreen *screen,
|
|||||||
if (w->screen == screen &&
|
if (w->screen == screen &&
|
||||||
w->type == META_WINDOW_DESKTOP)
|
w->type == META_WINDOW_DESKTOP)
|
||||||
{
|
{
|
||||||
meta_window_focus (w, timestamp);
|
meta_window_focus_explicitly (w, timestamp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -696,4 +696,12 @@ void meta_window_set_shape_region (MetaWindow *window,
|
|||||||
cairo_region_t *region);
|
cairo_region_t *region);
|
||||||
void meta_window_update_shape_region_x11 (MetaWindow *window);
|
void meta_window_update_shape_region_x11 (MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_window_handle_enter (MetaWindow *window,
|
||||||
|
guint32 timestamp,
|
||||||
|
guint root_x,
|
||||||
|
guint root_y);
|
||||||
|
|
||||||
|
void meta_window_focus_implicitly (MetaWindow *window,
|
||||||
|
guint32 timestamp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -49,6 +49,7 @@
|
|||||||
#include "constraints.h"
|
#include "constraints.h"
|
||||||
#include "mutter-enum-types.h"
|
#include "mutter-enum-types.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include <meta/compositor-mutter.h>
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/Xlibint.h> /* For display->resource_mask */
|
#include <X11/Xlibint.h> /* For display->resource_mask */
|
||||||
@@ -3182,7 +3183,7 @@ meta_window_show (MetaWindow *window)
|
|||||||
|
|
||||||
timestamp = meta_display_get_current_time_roundtrip (window->display);
|
timestamp = meta_display_get_current_time_roundtrip (window->display);
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -4224,7 +4225,7 @@ meta_window_shade (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Re-focusing window %s after shading it\n",
|
"Re-focusing window %s after shading it\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
set_net_wm_state (window);
|
set_net_wm_state (window);
|
||||||
}
|
}
|
||||||
@@ -4248,7 +4249,7 @@ meta_window_unshade (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing window %s after unshading it\n",
|
"Focusing window %s after unshading it\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
set_net_wm_state (window);
|
set_net_wm_state (window);
|
||||||
}
|
}
|
||||||
@@ -4347,7 +4348,7 @@ window_activate (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing window %s due to activation\n",
|
"Focusing window %s due to activation\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
meta_window_check_alive (window, timestamp);
|
meta_window_check_alive (window, timestamp);
|
||||||
}
|
}
|
||||||
@@ -5971,17 +5972,18 @@ get_modal_transient (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX META_EFFECT_FOCUS */
|
/* XXX META_EFFECT_FOCUS */
|
||||||
void
|
static void
|
||||||
meta_window_focus (MetaWindow *window,
|
meta_window_focus_internal (MetaWindow *window,
|
||||||
guint32 timestamp)
|
guint32 timestamp,
|
||||||
|
gboolean explicit_focus)
|
||||||
{
|
{
|
||||||
MetaWindow *modal_transient;
|
MetaWindow *modal_transient;
|
||||||
|
|
||||||
g_return_if_fail (!window->override_redirect);
|
g_return_if_fail (!window->override_redirect);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Setting input focus to window %s, input: %d take_focus: %d\n",
|
"%s setting input focus to window %s, input: %d take_focus: %d\n",
|
||||||
window->desc, window->input, window->take_focus);
|
explicit_focus ? "Explicitly" : "Implicitly", window->desc, window->input, window->take_focus);
|
||||||
|
|
||||||
if (window->display->grab_window &&
|
if (window->display->grab_window &&
|
||||||
window->display->grab_window->all_keys_grabbed)
|
window->display->grab_window->all_keys_grabbed)
|
||||||
@@ -6016,15 +6018,16 @@ meta_window_focus (MetaWindow *window,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For output-only or shaded windows, focus the frame.
|
/* For output-only or shaded windows, focus the frame if it was
|
||||||
* This seems to result in the client window getting key events
|
* an explicit focus event. This seems to result in the client
|
||||||
* though, so I don't know if it's icccm-compliant.
|
* window getting key events though, so I don't know if it's
|
||||||
|
* icccm-compliant.
|
||||||
*
|
*
|
||||||
* Still, we have to do this or keynav breaks for these windows.
|
* Still, we have to do this or keynav breaks for these windows.
|
||||||
*/
|
*/
|
||||||
if (window->frame &&
|
if (window->frame &&
|
||||||
(window->shaded ||
|
(window->shaded ||
|
||||||
!(window->input || window->take_focus)))
|
(explicit_focus && !window->input && !window->take_focus)))
|
||||||
{
|
{
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
@@ -6067,6 +6070,40 @@ meta_window_focus (MetaWindow *window,
|
|||||||
/* meta_effect_run_focus(window, NULL, NULL); */
|
/* meta_effect_run_focus(window, NULL, NULL); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_window_focus_explicitly:
|
||||||
|
* @window: A #MetaWindow
|
||||||
|
* @timestamp: The timestamp to focus the window with
|
||||||
|
*
|
||||||
|
* Explicitly grab the window's focus. This should be used in cases
|
||||||
|
* where the user wants to focus the window with Alt-Tab, pagers,
|
||||||
|
* or other means like that, as opposed to simply clicking on the
|
||||||
|
* window or other focus-modes like focus-follows-mouse.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_window_focus_explicitly (MetaWindow *window,
|
||||||
|
guint32 timestamp)
|
||||||
|
{
|
||||||
|
meta_window_focus_internal (window, timestamp, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_window_focus_implicitly:
|
||||||
|
* @window: A #MetaWindow
|
||||||
|
* @timestamp: The timestamp to focus the window with
|
||||||
|
*
|
||||||
|
* Implicitly focus the window. This should be done if the user
|
||||||
|
* simply clicks on the window. Most of the time, this should be
|
||||||
|
* handled by mutter internally, and you should never have to
|
||||||
|
* call this.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_window_focus_implicitly (MetaWindow *window,
|
||||||
|
guint32 timestamp)
|
||||||
|
{
|
||||||
|
meta_window_focus_internal (window, timestamp, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_change_workspace_without_transients (MetaWindow *window,
|
meta_window_change_workspace_without_transients (MetaWindow *window,
|
||||||
MetaWorkspace *workspace)
|
MetaWorkspace *workspace)
|
||||||
@@ -11432,3 +11469,185 @@ meta_window_can_close (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
return window->has_close_func;
|
return window->has_close_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reset_ignored_crossing_serials (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < N_IGNORED_CROSSING_SERIALS)
|
||||||
|
{
|
||||||
|
display->ignored_crossing_serials[i] = 0;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
display->ungrab_should_not_cause_focus_window = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MetaWindow *window;
|
||||||
|
int pointer_x;
|
||||||
|
int pointer_y;
|
||||||
|
} MetaFocusData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
mouse_mode_focus (MetaWindow *window,
|
||||||
|
guint32 timestamp)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
|
||||||
|
if (window->type != META_WINDOW_DESKTOP)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Focusing %s at time %u.\n", window->desc, timestamp);
|
||||||
|
|
||||||
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
|
|
||||||
|
if (meta_prefs_get_auto_raise ())
|
||||||
|
meta_display_queue_autoraise_callback (display, window);
|
||||||
|
else
|
||||||
|
meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* In mouse focus mode, we defocus when the mouse *enters*
|
||||||
|
* the DESKTOP window, instead of defocusing on LeaveNotify.
|
||||||
|
* This is because having the mouse enter override-redirect
|
||||||
|
* child windows unfortunately causes LeaveNotify events that
|
||||||
|
* we can't distinguish from the mouse actually leaving the
|
||||||
|
* toplevel window as we expect. But, since we filter out
|
||||||
|
* EnterNotify events on override-redirect windows, this
|
||||||
|
* alternative mechanism works great.
|
||||||
|
*/
|
||||||
|
if (meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE &&
|
||||||
|
display->focus_window != NULL)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Unsetting focus from %s due to mouse entering "
|
||||||
|
"the DESKTOP window\n",
|
||||||
|
display->focus_window->desc);
|
||||||
|
meta_display_focus_the_no_focus_window (display,
|
||||||
|
window->screen,
|
||||||
|
timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
window_focus_on_pointer_rest_callback (gpointer data)
|
||||||
|
{
|
||||||
|
MetaFocusData *focus_data = data;
|
||||||
|
MetaWindow *window = focus_data->window;
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
MetaScreen *screen = window->screen;
|
||||||
|
Window root, child;
|
||||||
|
double root_x, root_y, x, y;
|
||||||
|
guint32 timestamp;
|
||||||
|
XIButtonState buttons;
|
||||||
|
XIModifierState mods;
|
||||||
|
XIGroupState group;
|
||||||
|
|
||||||
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
XIQueryPointer (display->xdisplay,
|
||||||
|
META_VIRTUAL_CORE_POINTER_ID,
|
||||||
|
screen->xroot,
|
||||||
|
&root, &child,
|
||||||
|
&root_x, &root_y, &x, &y,
|
||||||
|
&buttons, &mods, &group);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
free (buttons.mask);
|
||||||
|
|
||||||
|
if (root_x != focus_data->pointer_x ||
|
||||||
|
root_y != focus_data->pointer_y)
|
||||||
|
{
|
||||||
|
focus_data->pointer_x = root_x;
|
||||||
|
focus_data->pointer_y = root_y;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Explicitly check for the overlay window, as get_focus_window_at_point()
|
||||||
|
* may return windows that extend underneath the chrome (like
|
||||||
|
* override-redirect or DESKTOP windows)
|
||||||
|
*/
|
||||||
|
if (child == meta_get_overlay_window (screen))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
window =
|
||||||
|
meta_stack_get_default_focus_window_at_point (screen->stack,
|
||||||
|
screen->active_workspace,
|
||||||
|
None, root_x, root_y);
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
timestamp = meta_display_get_current_time_roundtrip (display);
|
||||||
|
mouse_mode_focus (window, timestamp);
|
||||||
|
|
||||||
|
out:
|
||||||
|
display->focus_timeout_id = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The interval, in milliseconds, we use in focus-follows-mouse
|
||||||
|
* mode to check whether the pointer has stopped moving after a
|
||||||
|
* crossing event.
|
||||||
|
*/
|
||||||
|
#define FOCUS_TIMEOUT_DELAY 25
|
||||||
|
|
||||||
|
static void
|
||||||
|
queue_focus_callback (MetaDisplay *display,
|
||||||
|
MetaWindow *window,
|
||||||
|
int pointer_x,
|
||||||
|
int pointer_y)
|
||||||
|
{
|
||||||
|
MetaFocusData *focus_data;
|
||||||
|
|
||||||
|
focus_data = g_new (MetaFocusData, 1);
|
||||||
|
focus_data->window = window;
|
||||||
|
focus_data->pointer_x = pointer_x;
|
||||||
|
focus_data->pointer_y = pointer_y;
|
||||||
|
|
||||||
|
if (display->focus_timeout_id != 0)
|
||||||
|
g_source_remove (display->focus_timeout_id);
|
||||||
|
|
||||||
|
display->focus_timeout_id =
|
||||||
|
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
||||||
|
FOCUS_TIMEOUT_DELAY,
|
||||||
|
window_focus_on_pointer_rest_callback,
|
||||||
|
focus_data,
|
||||||
|
g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_handle_enter (MetaWindow *window,
|
||||||
|
guint32 timestamp,
|
||||||
|
guint root_x,
|
||||||
|
guint root_y)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
|
||||||
|
switch (meta_prefs_get_focus_mode ())
|
||||||
|
{
|
||||||
|
case G_DESKTOP_FOCUS_MODE_SLOPPY:
|
||||||
|
case G_DESKTOP_FOCUS_MODE_MOUSE:
|
||||||
|
display->mouse_mode = TRUE;
|
||||||
|
if (window->type != META_WINDOW_DOCK)
|
||||||
|
{
|
||||||
|
if (meta_prefs_get_focus_change_on_pointer_rest())
|
||||||
|
queue_focus_callback (display, window, root_x, root_y);
|
||||||
|
else
|
||||||
|
mouse_mode_focus (window, timestamp);
|
||||||
|
|
||||||
|
/* stop ignoring stuff */
|
||||||
|
reset_ignored_crossing_serials (display);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case G_DESKTOP_FOCUS_MODE_CLICK:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1256,7 +1256,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
|||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing mouse window %s\n", window->desc);
|
"Focusing mouse window %s\n", window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workspace->screen->display->autoraise_window != window &&
|
if (workspace->screen->display->autoraise_window != window &&
|
||||||
@@ -1319,7 +1319,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
|||||||
"Focusing %s, ancestor of %s\n",
|
"Focusing %s, ancestor of %s\n",
|
||||||
ancestor->desc, not_this_one->desc);
|
ancestor->desc, not_this_one->desc);
|
||||||
|
|
||||||
meta_window_focus (ancestor, timestamp);
|
meta_window_focus_explicitly (ancestor, timestamp);
|
||||||
|
|
||||||
/* Also raise the window if in click-to-focus */
|
/* Also raise the window if in click-to-focus */
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
@@ -1338,7 +1338,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing workspace MRU window %s\n", window->desc);
|
"Focusing workspace MRU window %s\n", window->desc);
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
/* Also raise the window if in click-to-focus */
|
/* Also raise the window if in click-to-focus */
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
|
@@ -227,7 +227,7 @@ void meta_window_stick (MetaWindow *window);
|
|||||||
void meta_window_unstick (MetaWindow *window);
|
void meta_window_unstick (MetaWindow *window);
|
||||||
|
|
||||||
void meta_window_kill (MetaWindow *window);
|
void meta_window_kill (MetaWindow *window);
|
||||||
void meta_window_focus (MetaWindow *window,
|
void meta_window_focus_explicitly (MetaWindow *window,
|
||||||
guint32 timestamp);
|
guint32 timestamp);
|
||||||
|
|
||||||
void meta_window_check_alive (MetaWindow *window,
|
void meta_window_check_alive (MetaWindow *window,
|
||||||
|
Reference in New Issue
Block a user