mirror of
https://github.com/brl/mutter.git
synced 2025-06-13 16:59:30 +00:00
wayland: refactor window destruction and focus
The previous code was leaving focus fields dirty in MetaWaylandPointer and MetaWaylandKeyboard at time (which could crash the X server because of invalid object IDs) The new code is more tighly integrated in the normal X11 code for handling keyboard focus (meaning that the core idea of input focus is also correct now), so that meta_window_unmanage() can do the right thing. As a side benefit, clicking on wayland clients now unfocus X11 clients. For the mouse focus, we need to clear the surface pointer when the metawindowactor is destroyed (even if the actual actor is kept alive for effects), so that a repick finds a different pointer focus. https://bugzilla.gnome.org/show_bug.cgi?id=705859
This commit is contained in:
@ -1902,9 +1902,14 @@ update_focus_window (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gulong serial)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *compositor;
|
||||
#endif
|
||||
|
||||
display->focus_serial = serial;
|
||||
|
||||
if (display->focus_xwindow == xwindow)
|
||||
if (display->focus_xwindow == xwindow &&
|
||||
display->focus_window == window)
|
||||
return;
|
||||
|
||||
if (display->focus_window)
|
||||
@ -1938,6 +1943,20 @@ update_focus_window (MetaDisplay *display,
|
||||
else
|
||||
meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
if (meta_display_xwindow_is_a_no_focus_window (display, xwindow))
|
||||
meta_wayland_compositor_set_input_focus (compositor, NULL);
|
||||
else if (window && window->surface)
|
||||
meta_wayland_compositor_set_input_focus (compositor, window);
|
||||
else
|
||||
meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface");
|
||||
}
|
||||
#endif
|
||||
|
||||
g_object_notify (G_OBJECT (display), "focus-window");
|
||||
meta_display_update_active_window_hint (display);
|
||||
}
|
||||
@ -1974,17 +1993,15 @@ timestamp_too_old (MetaDisplay *display,
|
||||
static void
|
||||
request_xserver_input_focus_change (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *meta_window,
|
||||
Window xwindow,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *meta_window;
|
||||
gulong serial;
|
||||
|
||||
if (timestamp_too_old (display, ×tamp))
|
||||
return;
|
||||
|
||||
meta_window = meta_display_lookup_x_window (display, xwindow);
|
||||
|
||||
meta_error_trap_push (display);
|
||||
|
||||
/* In order for mutter to know that the focus request succeeded, we track
|
||||
@ -2651,15 +2668,6 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
}
|
||||
break;
|
||||
case XI_FocusIn:
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor =
|
||||
meta_wayland_compositor_get_default ();
|
||||
meta_wayland_compositor_set_input_focus (compositor, window);
|
||||
}
|
||||
#endif
|
||||
/* fall through */
|
||||
case XI_FocusOut:
|
||||
/* libXi does not properly copy the serial to the XIEnterEvent, so pull it
|
||||
* from the parent XAnyEvent.
|
||||
@ -5884,6 +5892,7 @@ meta_display_set_input_focus_window (MetaDisplay *display,
|
||||
{
|
||||
request_xserver_input_focus_change (display,
|
||||
window->screen,
|
||||
window,
|
||||
focus_frame ? window->frame->xwindow : window->xwindow,
|
||||
timestamp);
|
||||
}
|
||||
@ -5931,6 +5940,7 @@ meta_display_set_input_focus_xwindow (MetaDisplay *display,
|
||||
{
|
||||
request_xserver_input_focus_change (display,
|
||||
screen,
|
||||
NULL,
|
||||
window,
|
||||
timestamp);
|
||||
}
|
||||
@ -5942,6 +5952,7 @@ meta_display_focus_the_no_focus_window (MetaDisplay *display,
|
||||
{
|
||||
request_xserver_input_focus_change (display,
|
||||
screen,
|
||||
NULL,
|
||||
screen->no_focus_window,
|
||||
timestamp);
|
||||
}
|
||||
|
@ -62,6 +62,10 @@
|
||||
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "meta-wayland-private.h"
|
||||
#endif
|
||||
|
||||
/* Windows that unmaximize to a size bigger than that fraction of the workarea
|
||||
* will be scaled down to that size (while maintaining aspect ratio).
|
||||
* Windows that cover an area greater then this size are automaximized on map.
|
||||
@ -2103,6 +2107,11 @@ meta_window_unmanage (MetaWindow *window,
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (window->surface)
|
||||
meta_wayland_surface_free (window->surface);
|
||||
#endif
|
||||
|
||||
meta_prefs_remove_listener (prefs_changed_callback, window);
|
||||
|
||||
meta_screen_queue_check_fullscreen (window->screen);
|
||||
|
Reference in New Issue
Block a user