зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1745590 [Wayland] Don't use external GtkWidget as focus source, r=emilio
We get wl_keyboard_enter event for all wl_surfaces which includes file dialogs owned by Gtk. We can't use such wl_surface as focus source as it's not owned/managed by Firefox. When we request focus on Wayland, check that we should have the focus (by gFocusWindow) and also check if we really have it (by comparing wl_surface owned by gFocusWindow and wl_surface obtained from wl_keyboard_enter). Differential Revision: https://phabricator.services.mozilla.com/D133634
This commit is contained in:
Родитель
83c32ae54f
Коммит
431724df87
|
@ -2424,17 +2424,23 @@ void KeymapWrapper::WillDispatchKeyboardEventInternal(
|
|||
#ifdef MOZ_WAYLAND
|
||||
void KeymapWrapper::SetFocusIn(wl_surface* aFocusSurface,
|
||||
uint32_t aFocusSerial) {
|
||||
LOGW("KeymapWrapper::SetFocusIn() surface %p ID %d serial %d", aFocusSurface,
|
||||
aFocusSurface ? wl_proxy_get_id((struct wl_proxy*)aFocusSurface) : 0,
|
||||
aFocusSerial);
|
||||
|
||||
KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
|
||||
keymapWrapper->mFocusSurface = aFocusSurface;
|
||||
keymapWrapper->mFocusSerial = aFocusSerial;
|
||||
}
|
||||
|
||||
// aFocusSurface can be null in case that focused surface is already destroyed.
|
||||
void KeymapWrapper::SetFocusOut(wl_surface* aFocusSurface) {
|
||||
KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
|
||||
if (aFocusSurface == keymapWrapper->mFocusSurface) {
|
||||
keymapWrapper->mFocusSurface = nullptr;
|
||||
keymapWrapper->mFocusSerial = 0;
|
||||
}
|
||||
LOGW("KeymapWrapper::SetFocusOut surface %p ID %d", aFocusSurface,
|
||||
aFocusSurface ? wl_proxy_get_id((struct wl_proxy*)aFocusSurface) : 0);
|
||||
|
||||
keymapWrapper->mFocusSurface = nullptr;
|
||||
keymapWrapper->mFocusSerial = 0;
|
||||
}
|
||||
|
||||
void KeymapWrapper::GetFocusInfo(wl_surface** aFocusSurface,
|
||||
|
@ -2453,7 +2459,6 @@ wl_seat* KeymapWrapper::GetSeat() {
|
|||
KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
|
||||
return keymapWrapper->mSeat;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace widget
|
||||
|
|
|
@ -2845,6 +2845,9 @@ void nsWindow::FocusWaylandWindow(const char* aTokenID) {
|
|||
return;
|
||||
}
|
||||
|
||||
LOG(" requesting xdg-activation, surface ID %d",
|
||||
wl_proxy_get_id((struct wl_proxy*)surface));
|
||||
|
||||
xdg_activation_v1* xdg_activation = WaylandDisplayGet()->GetXdgActivation();
|
||||
xdg_activation_v1_activate(xdg_activation, aTokenID, surface);
|
||||
}
|
||||
|
@ -2862,12 +2865,17 @@ static const struct xdg_activation_token_v1_listener token_listener = {
|
|||
};
|
||||
|
||||
void nsWindow::RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow) {
|
||||
LOG("nsWindow::RequestWindowFocusWayland(%p)", (void*)aWindow);
|
||||
LOGW("nsWindow::RequestFocusWaylandWindow(%p) gFocusWindow %p",
|
||||
(void*)aWindow, gFocusWindow);
|
||||
|
||||
if (!gFocusWindow) {
|
||||
LOGW(" missing gFocusWindow, quit.");
|
||||
}
|
||||
|
||||
RefPtr<nsWaylandDisplay> display = WaylandDisplayGet();
|
||||
xdg_activation_v1* xdg_activation = display->GetXdgActivation();
|
||||
if (!xdg_activation) {
|
||||
LOG(" xdg-activation is missing, quit.");
|
||||
LOGW(" xdg-activation is missing, quit.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2875,13 +2883,25 @@ void nsWindow::RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow) {
|
|||
uint32_t focusSerial;
|
||||
KeymapWrapper::GetFocusInfo(&focusSurface, &focusSerial);
|
||||
if (!focusSurface) {
|
||||
LOG(" We're missing focused window, quit.");
|
||||
LOGW(" We're missing focused window, quit.");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(" requesting xdg-activation token, surface ID %d serial %d seat ID %d",
|
||||
wl_proxy_get_id((struct wl_proxy*)focusSurface), focusSerial,
|
||||
wl_proxy_get_id((struct wl_proxy*)KeymapWrapper::GetSeat()));
|
||||
GdkWindow* gdkWindow = gtk_widget_get_window(gFocusWindow->mShell);
|
||||
wl_surface* surface =
|
||||
gdkWindow ? gdk_wayland_window_get_wl_surface(gdkWindow) : nullptr;
|
||||
if (focusSurface != surface) {
|
||||
LOGW(" focused surface %p and gFocusWindow surface %p don't match, quit.",
|
||||
focusSurface, surface);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGW(
|
||||
" requesting xdg-activation token, surface %p ID %d serial %d seat ID "
|
||||
"%d",
|
||||
focusSurface,
|
||||
focusSurface ? wl_proxy_get_id((struct wl_proxy*)focusSurface) : 0,
|
||||
focusSerial, wl_proxy_get_id((struct wl_proxy*)KeymapWrapper::GetSeat()));
|
||||
|
||||
// Store activation token at activated window for further release.
|
||||
g_clear_pointer(&aWindow->mXdgToken, xdg_activation_token_v1_destroy);
|
||||
|
|
|
@ -386,8 +386,7 @@ class nsWindow final : public nsBaseWidget {
|
|||
|
||||
#ifdef MOZ_WAYLAND
|
||||
// Use xdg-activation protocol to transfer focus from gFocusWindow to aWindow.
|
||||
// RequestFocusWaylandWindow needs to be called on focused window only.
|
||||
void RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow);
|
||||
static void RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow);
|
||||
void FocusWaylandWindow(const char* aTokenID);
|
||||
|
||||
bool GetCSDDecorationOffset(int* aDx, int* aDy);
|
||||
|
|
Загрузка…
Ссылка в новой задаче