зеркало из 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
|
#ifdef MOZ_WAYLAND
|
||||||
void KeymapWrapper::SetFocusIn(wl_surface* aFocusSurface,
|
void KeymapWrapper::SetFocusIn(wl_surface* aFocusSurface,
|
||||||
uint32_t aFocusSerial) {
|
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* keymapWrapper = KeymapWrapper::GetInstance();
|
||||||
keymapWrapper->mFocusSurface = aFocusSurface;
|
keymapWrapper->mFocusSurface = aFocusSurface;
|
||||||
keymapWrapper->mFocusSerial = aFocusSerial;
|
keymapWrapper->mFocusSerial = aFocusSerial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// aFocusSurface can be null in case that focused surface is already destroyed.
|
||||||
void KeymapWrapper::SetFocusOut(wl_surface* aFocusSurface) {
|
void KeymapWrapper::SetFocusOut(wl_surface* aFocusSurface) {
|
||||||
KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
|
KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
|
||||||
if (aFocusSurface == keymapWrapper->mFocusSurface) {
|
LOGW("KeymapWrapper::SetFocusOut surface %p ID %d", aFocusSurface,
|
||||||
keymapWrapper->mFocusSurface = nullptr;
|
aFocusSurface ? wl_proxy_get_id((struct wl_proxy*)aFocusSurface) : 0);
|
||||||
keymapWrapper->mFocusSerial = 0;
|
|
||||||
}
|
keymapWrapper->mFocusSurface = nullptr;
|
||||||
|
keymapWrapper->mFocusSerial = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeymapWrapper::GetFocusInfo(wl_surface** aFocusSurface,
|
void KeymapWrapper::GetFocusInfo(wl_surface** aFocusSurface,
|
||||||
|
@ -2453,7 +2459,6 @@ wl_seat* KeymapWrapper::GetSeat() {
|
||||||
KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
|
KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
|
||||||
return keymapWrapper->mSeat;
|
return keymapWrapper->mSeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace widget
|
} // namespace widget
|
||||||
|
|
|
@ -2845,6 +2845,9 @@ void nsWindow::FocusWaylandWindow(const char* aTokenID) {
|
||||||
return;
|
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* xdg_activation = WaylandDisplayGet()->GetXdgActivation();
|
||||||
xdg_activation_v1_activate(xdg_activation, aTokenID, surface);
|
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) {
|
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();
|
RefPtr<nsWaylandDisplay> display = WaylandDisplayGet();
|
||||||
xdg_activation_v1* xdg_activation = display->GetXdgActivation();
|
xdg_activation_v1* xdg_activation = display->GetXdgActivation();
|
||||||
if (!xdg_activation) {
|
if (!xdg_activation) {
|
||||||
LOG(" xdg-activation is missing, quit.");
|
LOGW(" xdg-activation is missing, quit.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2875,13 +2883,25 @@ void nsWindow::RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow) {
|
||||||
uint32_t focusSerial;
|
uint32_t focusSerial;
|
||||||
KeymapWrapper::GetFocusInfo(&focusSurface, &focusSerial);
|
KeymapWrapper::GetFocusInfo(&focusSurface, &focusSerial);
|
||||||
if (!focusSurface) {
|
if (!focusSurface) {
|
||||||
LOG(" We're missing focused window, quit.");
|
LOGW(" We're missing focused window, quit.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(" requesting xdg-activation token, surface ID %d serial %d seat ID %d",
|
GdkWindow* gdkWindow = gtk_widget_get_window(gFocusWindow->mShell);
|
||||||
wl_proxy_get_id((struct wl_proxy*)focusSurface), focusSerial,
|
wl_surface* surface =
|
||||||
wl_proxy_get_id((struct wl_proxy*)KeymapWrapper::GetSeat()));
|
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.
|
// Store activation token at activated window for further release.
|
||||||
g_clear_pointer(&aWindow->mXdgToken, xdg_activation_token_v1_destroy);
|
g_clear_pointer(&aWindow->mXdgToken, xdg_activation_token_v1_destroy);
|
||||||
|
|
|
@ -386,8 +386,7 @@ class nsWindow final : public nsBaseWidget {
|
||||||
|
|
||||||
#ifdef MOZ_WAYLAND
|
#ifdef MOZ_WAYLAND
|
||||||
// Use xdg-activation protocol to transfer focus from gFocusWindow to aWindow.
|
// Use xdg-activation protocol to transfer focus from gFocusWindow to aWindow.
|
||||||
// RequestFocusWaylandWindow needs to be called on focused window only.
|
static void RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow);
|
||||||
void RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow);
|
|
||||||
void FocusWaylandWindow(const char* aTokenID);
|
void FocusWaylandWindow(const char* aTokenID);
|
||||||
|
|
||||||
bool GetCSDDecorationOffset(int* aDx, int* aDy);
|
bool GetCSDDecorationOffset(int* aDx, int* aDy);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче