firefox/D133209.diff

198 lines
6.2 KiB
Diff

diff --git a/widget/gtk/nsGtkKeyUtils.h b/widget/gtk/nsGtkKeyUtils.h
--- a/widget/gtk/nsGtkKeyUtils.h
+++ b/widget/gtk/nsGtkKeyUtils.h
@@ -202,6 +202,22 @@
* from xkb_keymap. We call that from Wayland backend routines.
*/
static void SetModifierMasks(xkb_keymap* aKeymap);
+
+ /**
+ * Wayland global focus handlers
+ */
+ static void SetFocusIn(wl_surface* aFocusSurface, uint32_t aFocusSerial);
+ static void SetFocusOut(wl_surface* aFocusSurface);
+ static void GetFocusInfo(wl_surface** aFocusSurface, uint32_t* aFocusSerial);
+
+ static void SetSeat(wl_seat* aSeat);
+ static wl_seat* GetSeat();
+
+ /**
+ * EnsureInstance() is provided on Wayland to register Wayland callbacks
+ * early.
+ */
+ static void EnsureInstance();
#endif
/**
@@ -467,6 +483,12 @@
void SetModifierMask(xkb_keymap* aKeymap, ModifierIndex aModifierIndex,
const char* aModifierName);
#endif
+
+#ifdef MOZ_WAYLAND
+ wl_seat* mSeat = nullptr;
+ wl_surface* mFocusSurface = nullptr;
+ uint32_t mFocusSerial = 0;
+#endif
};
} // namespace widget
diff --git a/widget/gtk/nsGtkKeyUtils.cpp b/widget/gtk/nsGtkKeyUtils.cpp
--- a/widget/gtk/nsGtkKeyUtils.cpp
+++ b/widget/gtk/nsGtkKeyUtils.cpp
@@ -331,6 +331,10 @@
return sInstance;
}
+#ifdef MOZ_WAYLAND
+void KeymapWrapper::EnsureInstance() { (void)GetInstance(); }
+#endif
+
/* static */
void KeymapWrapper::Shutdown() {
if (sInstance) {
@@ -720,10 +724,15 @@
static void keyboard_handle_enter(void* data, struct wl_keyboard* keyboard,
uint32_t serial, struct wl_surface* surface,
- struct wl_array* keys) {}
+ struct wl_array* keys) {
+ KeymapWrapper::SetFocusIn(surface, serial);
+}
+
static void keyboard_handle_leave(void* data, struct wl_keyboard* keyboard,
uint32_t serial, struct wl_surface* surface) {
+ KeymapWrapper::SetFocusOut(surface);
}
+
static void keyboard_handle_key(void* data, struct wl_keyboard* keyboard,
uint32_t serial, uint32_t time, uint32_t key,
uint32_t state) {}
@@ -760,6 +769,7 @@
if (strcmp(interface, "wl_seat") == 0) {
auto* seat =
WaylandRegistryBind<wl_seat>(registry, id, &wl_seat_interface, 1);
+ KeymapWrapper::SetSeat(seat);
wl_seat_add_listener(seat, &seat_listener, data);
}
}
@@ -2411,5 +2421,40 @@
altLatinCharCodes.mShiftedCharCode));
}
+#ifdef MOZ_WAYLAND
+void KeymapWrapper::SetFocusIn(wl_surface* aFocusSurface,
+ uint32_t aFocusSerial) {
+ KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
+ keymapWrapper->mFocusSurface = aFocusSurface;
+ keymapWrapper->mFocusSerial = aFocusSerial;
+}
+
+void KeymapWrapper::SetFocusOut(wl_surface* aFocusSurface) {
+ KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
+ if (aFocusSurface == keymapWrapper->mFocusSurface) {
+ keymapWrapper->mFocusSurface = nullptr;
+ keymapWrapper->mFocusSerial = 0;
+ }
+}
+
+void KeymapWrapper::GetFocusInfo(wl_surface** aFocusSurface,
+ uint32_t* aFocusSerial) {
+ KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
+ *aFocusSurface = keymapWrapper->mFocusSurface;
+ *aFocusSerial = keymapWrapper->mFocusSerial;
+}
+
+void KeymapWrapper::SetSeat(wl_seat* aSeat) {
+ KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
+ keymapWrapper->mSeat = aSeat;
+}
+
+wl_seat* KeymapWrapper::GetSeat() {
+ KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance();
+ return keymapWrapper->mSeat;
+}
+
+#endif
+
} // namespace widget
} // namespace mozilla
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -2862,8 +2862,7 @@
};
void nsWindow::RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow) {
- LOG("nsWindow::RequestWindowFocusWayland(%p) gFocusWindow [%p]",
- (void*)aWindow, gFocusWindow);
+ LOG("nsWindow::RequestWindowFocusWayland(%p)", (void*)aWindow);
RefPtr<nsWaylandDisplay> display = WaylandDisplayGet();
xdg_activation_v1* xdg_activation = display->GetXdgActivation();
@@ -2872,17 +2871,11 @@
return;
}
- // We use xdg-activation protocol to transfer focus from gFocusWindow to
- // aWindow. Quit if no window is focused.
- if (gFocusWindow != this) {
- LOG(" there isn't any focused window to transfer focus from, quit.");
- return;
- }
-
- wl_surface* surface =
- mGdkWindow ? gdk_wayland_window_get_wl_surface(mGdkWindow) : nullptr;
- if (!surface) {
- LOG(" requesting window is hidden/unmapped, quit.");
+ wl_surface* focusSurface;
+ uint32_t focusSerial;
+ KeymapWrapper::GetFocusInfo(&focusSurface, &focusSerial);
+ if (!focusSurface) {
+ LOG(" We're missing focused window, quit.");
return;
}
@@ -2894,9 +2887,9 @@
// callback.
xdg_activation_token_v1_add_listener(aWindow->mXdgToken, &token_listener,
do_AddRef(aWindow).take());
- xdg_activation_token_v1_set_serial(aWindow->mXdgToken, GetLastUserInputTime(),
- display->GetSeat());
- xdg_activation_token_v1_set_surface(aWindow->mXdgToken, surface);
+ xdg_activation_token_v1_set_serial(aWindow->mXdgToken, focusSerial,
+ KeymapWrapper::GetSeat());
+ xdg_activation_token_v1_set_surface(aWindow->mXdgToken, focusSurface);
xdg_activation_token_v1_commit(aWindow->mXdgToken);
}
#endif
@@ -2959,11 +2952,7 @@
#ifdef MOZ_WAYLAND
if (GdkIsWaylandDisplay()) {
- if (gFocusWindow) {
- gFocusWindow->RequestFocusWaylandWindow(toplevelWindow);
- } else {
- LOG(" RequestFocusWaylandWindow(): we're missing focused window!");
- }
+ RequestFocusWaylandWindow(toplevelWindow);
}
#endif
if (GTKToolkit) GTKToolkit->SetFocusTimestamp(0);
@@ -5359,6 +5348,14 @@
a11y::PreInit();
#endif
+#ifdef MOZ_WAYLAND
+ // Ensure that KeymapWrapper is created on Wayland as we need it for
+ // keyboard focus tracking.
+ if (GdkIsWaylandDisplay()) {
+ KeymapWrapper::EnsureInstance();
+ }
+#endif
+
// Ensure that the toolkit is created.
nsGTKToolkit::GetToolkit();