Bug 1451816 - [Wayland] Avoid closing popup window on button-press on Weston r?stransky draft
authorTakuro Ashie <ashie@clear-code.com>
Thu, 14 Jun 2018 13:27:09 +0900
changeset 807303 8370581ea37c693fdd9f2c90c1e6a21d6ac0e580
parent 807260 c7a7df27ff38e2e75caebc44cb9ebf958b40b21e
push id113078
push userbmo:ashie@clear-code.com
push dateThu, 14 Jun 2018 04:49:53 +0000
reviewersstransky
bugs1451816
milestone62.0a1
Bug 1451816 - [Wayland] Avoid closing popup window on button-press on Weston r?stransky MozReview-Commit-ID: F9IEUseANbZ
widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -267,16 +267,19 @@ static void    drag_data_received_event_
                                            guint32 aTime,
                                            gpointer aData);
 
 /* initialization static functions */
 static nsresult    initialize_prefs        (void);
 
 static guint32 sLastUserInputTime = GDK_CURRENT_TIME;
 static guint32 sRetryGrabTime;
+#ifdef MOZ_WAYLAND
+static gint sPointerGrabbed = false;
+#endif // MOZ_WAYLAND
 
 static SystemTimeConverter<guint32>&
 TimeConverter() {
     static SystemTimeConverter<guint32> sTimeConverterSingleton;
     return sTimeConverterSingleton;
 }
 
 nsWindow::CSDSupportLevel nsWindow::sCSDSupportLevel = CSD_SUPPORT_UNKNOWN;
@@ -2882,16 +2885,28 @@ nsWindow::OnContainerFocusInEvent(GdkEve
     LOGFOCUS(("Events sent from focus in event [%p]\n", (void *)this));
 }
 
 void
 nsWindow::OnContainerFocusOutEvent(GdkEventFocus *aEvent)
 {
     LOGFOCUS(("OnContainerFocusOutEvent [%p]\n", (void *)this));
 
+#ifdef MOZ_WAYLAND
+    if (!mIsX11Display && sPointerGrabbed) {
+        // Bug 1451816
+        // On Weston, both focus-out & focus-in events are sent on button-press
+        // event (they aren't occured on other environments such as X11 or GNOME
+        // Shell on Wayland). Following code will destroy the popup menu so
+        // users can't activate items on it because activating item is handled
+        // on button-release event. To avoid it, ignore the focus-out event here.
+        return;
+    }
+#endif // MOZ_WAYLAND
+
     if (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog) {
         nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
         nsCOMPtr<nsIDragSession> dragSession;
         dragService->GetCurrentSession(getter_AddRefs(dragSession));
 
         // Rollup popups when a window is focused out unless a drag is occurring.
         // This check is because drags grab the keyboard and cause a focus out on
         // versions of GTK before 2.18.
@@ -4861,21 +4876,24 @@ nsWindow::GrabPointer(guint32 aTime)
         LOG(("GrabPointer: window not visible\n"));
         mRetryPointerGrab = true;
         return;
     }
 
     if (!mGdkWindow)
         return;
 
+#ifdef MOZ_WAYLAND
     if (!mIsX11Display) {
         // Don't to the grab on Wayland as it causes a regression
         // from Bug 1377084.
+        sPointerGrabbed = true;
         return;
     }
+#endif // MOZ_WAYLAND
 
     gint retval;
     // Note that we need GDK_TOUCH_MASK below to work around a GDK/X11 bug that
     // causes touch events that would normally be received by this client on
     // other windows to be discarded during the grab.
     retval = gdk_pointer_grab(mGdkWindow, TRUE,
                               (GdkEventMask)(GDK_BUTTON_PRESS_MASK |
                                              GDK_BUTTON_RELEASE_MASK |
@@ -4905,21 +4923,24 @@ nsWindow::GrabPointer(guint32 aTime)
 
 void
 nsWindow::ReleaseGrabs(void)
 {
     LOG(("ReleaseGrabs\n"));
 
     mRetryPointerGrab = false;
 
+#ifdef MOZ_WAYLAND
     if (!mIsX11Display) {
         // Don't to the ungrab on Wayland as it causes a regression
         // from Bug 1377084.
+        sPointerGrabbed = false;
         return;
     }
+#endif //MOZ_WAYLAND
 
     gdk_pointer_ungrab(GDK_CURRENT_TIME);
 }
 
 GtkWidget *
 nsWindow::GetToplevelWidget()
 {
     if (mShell) {