229f8cb
From 7ee77f157c166c1e7ddb6c2215518119fb6175df Mon Sep 17 00:00:00 2001
d82ce24
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
d82ce24
Date: Thu, 5 May 2016 15:19:24 +0100
d82ce24
Subject: [PATCH] gtk3: New Folder dialog from Templates dialog doesn't get
d82ce24
 keyboard focus
d82ce24
MIME-Version: 1.0
d82ce24
Content-Type: text/plain; charset=UTF-8
d82ce24
Content-Transfer-Encoding: 8bit
d82ce24
d82ce24
ctrl+shift+N, and click new folder, no keyboard input is accepted.
d82ce24
d82ce24
The dialogs don't get keyboard events, because the keyboard events
d82ce24
go to the top level window because of...
d82ce24
d82ce24
commit 011ce226e89ecabaf621603d692547c88061eaba
d82ce24
Author: Caolán McNamara <caolanm@redhat.com>
d82ce24
Date:   Tue Jan 19 13:22:10 2016 +0000
d82ce24
d82ce24
    Resolves: tdf#99604 ungrab modal dialogs
d82ce24
d82ce24
(should be tdf#96604) which stripped away the grab from the sub dialog
d82ce24
d82ce24
but I did that because menu dropdowns from comboboxes inside modal
d82ce24
dialogs didn't receive mouse focus otherwise.
d82ce24
d82ce24
I had set our "modal" dialogs to be truly modal and triggering that
d82ce24
problem with
d82ce24
d82ce24
commit 8d5822983e9b6a1e04874ce4d2c807fd0cf1ee04
d82ce24
Author: Caolán McNamara <caolanm@redhat.com>
d82ce24
Date:   Mon Dec 14 11:36:50 2015 +0000
d82ce24
d82ce24
    Related: rhbz#1290014 gtk3: use gtk_window_set_modal on modal dialogs
d82ce24
d82ce24
    which makes modal dialogs (which are most of them) place correctly
d82ce24
    under wayland. Modeless ones are still uselessly shoved far to the
d82ce24
    left, but this makes things near usable and gives the same "graying
d82ce24
    into the bg" effect for the main window as other gtk apps
d82ce24
d82ce24
which I still contend is "a good thing"
d82ce24
d82ce24
if we stop removing the grab from the modal dialog, then we still have
d82ce24
the problem that the menu dropdowns from comboboxes inside modal dialogs
d82ce24
don't receive mouse focus otherwise.
d82ce24
d82ce24
After trying to add/remove grabs around showing/hiding menus we run
d82ce24
into another pit of trouble
d82ce24
d82ce24
(commit 72e6a1365cb08986b542a5beb797634bca62d85b
d82ce24
Author: Caolán McNamara <caolanm@redhat.com>
d82ce24
Date:   Wed May 4 16:29:35 2016 +0100)
d82ce24
d82ce24
so, lets save the widget that has the grab before showing our first
d82ce24
menu, clear the grab, and restore it on hiding the first menu again.
d82ce24
d82ce24
and still ditch that metacity hack around thing at this point too
d82ce24
d82ce24
I truly hate this crap
d82ce24
d82ce24
Change-Id: If10e758585f156b33680b8d40355302cc1ae72f3
fe32e4c
fe32e4c
gtk3: use window groups so modal dialog are modal to their toplevel frame only
fe32e4c
fe32e4c
so e.g. launching help from a modal dialog gives a new toplevel window
fe32e4c
which is not blocked by the modal dialog on the other window.
fe32e4c
fe32e4c
likesize can go from one blocked e.g. writer window to calc and type away in
fe32e4c
there happily
fe32e4c
fe32e4c
Change-Id: Id9376b393514e91dfd667dfce132f1f37367084e
fe32e4c
(cherry picked from commit c80d34ad551efe858c47445b13370aa8223357c7)
fe32e4c
fe32e4c
gtk3: use gtk_window_group_get_current_grab instead of gtk_grab_get_current
fe32e4c
fe32e4c
now that we are using window groups, otherwise the problem of tdf#99604
fe32e4c
comes back
fe32e4c
fe32e4c
Change-Id: I7a940ea72bfd7fd4a7f68f1e60395d5014ce155c
fe32e4c
(cherry picked from commit 9b49e1817d4d045b724aed6267f8f00c6bf295cc)
229f8cb
229f8cb
Resolves: tdf#100327 gtk3 fpicker yes/no dialog modal trouble
229f8cb
229f8cb
not sure why we ever hid the file dialog when putting up the
229f8cb
yes/no dialog. So lets just do the more apparently sensible thing
229f8cb
on the gtk3 path and leave gtk2 alone.
229f8cb
229f8cb
Probably fallout from using window groups
229f8cb
229f8cb
(cherry picked from commit e50caebc02ee2045a38a39b4a4c644da0d678541)
229f8cb
(cherry picked from commit 83b7c1ae8068787212f757b9c8b9c317537a2dd2)
229f8cb
229f8cb
Change-Id: I4d0e8fae9568b050b674cf6ef4d8c88e65dd2ca1
d82ce24
---
229f8cb
 cui/source/customize/cfg.cxx             |  4 +--
229f8cb
 cui/source/customize/selector.cxx        | 15 ++-------
229f8cb
 cui/source/inc/selector.hxx              |  2 +-
229f8cb
 vcl/inc/unx/gtk/gtkframe.hxx             |  1 +
229f8cb
 vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx |  4 +++
229f8cb
 vcl/unx/gtk/fpicker/SalGtkPicker.cxx     |  2 ++
229f8cb
 vcl/unx/gtk3/gtk3gtkframe.cxx            | 57 +++++++++++++++++---------------
229f8cb
 7 files changed, 43 insertions(+), 42 deletions(-)
25b28e9
25b28e9
diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx
25b28e9
index 018cf39..72e8af5 100644
25b28e9
--- a/cui/source/customize/cfg.cxx
25b28e9
+++ b/cui/source/customize/cfg.cxx
25b28e9
@@ -2816,7 +2816,7 @@ IMPL_LINK_NOARG_TYPED( SvxMenuConfigPage, AddCommandsHdl, Button *, void )
25b28e9
 
25b28e9
     m_pSelectorDlg->SetImageProvider( GetSaveInData() );
25b28e9
 
25b28e9
-    m_pSelectorDlg->Show();
25b28e9
+    m_pSelectorDlg->Execute();
25b28e9
 }
25b28e9
 
25b28e9
 SaveInData* SvxMenuConfigPage::CreateSaveInData(
25b28e9
@@ -4702,7 +4702,7 @@ IMPL_LINK_NOARG_TYPED( SvxToolbarConfigPage, AddCommandsHdl, Button *, void )
25b28e9
 
25b28e9
     m_pSelectorDlg->SetImageProvider( GetSaveInData() );
25b28e9
 
25b28e9
-    m_pSelectorDlg->Show();
25b28e9
+    m_pSelectorDlg->Execute();
25b28e9
 }
25b28e9
 
25b28e9
 IMPL_LINK_NOARG_TYPED( SvxToolbarConfigPage, AddFunctionHdl, SvxScriptSelectorDialog&, void )
25b28e9
diff --git a/cui/source/customize/selector.cxx b/cui/source/customize/selector.cxx
25b28e9
index 28fbd87..5d76bb9 100644
25b28e9
--- a/cui/source/customize/selector.cxx
25b28e9
+++ b/cui/source/customize/selector.cxx
25b28e9
@@ -874,7 +874,7 @@ void SvxConfigGroupListBox::RequestingChildren( SvTreeListEntry *pEntry )
25b28e9
 
25b28e9
 SvxScriptSelectorDialog::SvxScriptSelectorDialog(
25b28e9
     vcl::Window* pParent, bool bShowSlots, const Reference< frame::XFrame >& xFrame)
25b28e9
-    : ModelessDialog(pParent, "MacroSelectorDialog", "cui/ui/macroselectordialog.ui")
25b28e9
+    : ModalDialog(pParent, "MacroSelectorDialog", "cui/ui/macroselectordialog.ui")
25b28e9
     , m_bShowSlots(bShowSlots)
25b28e9
 {
25b28e9
     get<FixedText>("libraryft")->Show(!m_bShowSlots);
25b28e9
@@ -934,7 +934,7 @@ void SvxScriptSelectorDialog::dispose()
25b28e9
     m_pOKButton.clear();
25b28e9
     m_pCancelButton.clear();
25b28e9
     m_pDescriptionText.clear();
25b28e9
-    ModelessDialog::dispose();
25b28e9
+    ModalDialog::dispose();
25b28e9
 }
25b28e9
 
25b28e9
 IMPL_LINK_TYPED( SvxScriptSelectorDialog, SelectHdl, SvTreeListBox*, pCtrl, void )
25b28e9
@@ -982,16 +982,7 @@ IMPL_LINK_TYPED( SvxScriptSelectorDialog, ClickHdl, Button *, pButton, void )
25b28e9
 {
25b28e9
     if (pButton == m_pCancelButton)
25b28e9
     {
25b28e9
-        // If we are displaying Slot API commands then the dialog is being
25b28e9
-        // run from Tools/Configure and we should not close it, just hide it
25b28e9
-        if ( !m_bShowSlots )
25b28e9
-        {
25b28e9
-            EndDialog();
25b28e9
-        }
25b28e9
-        else
25b28e9
-        {
25b28e9
-            Hide();
25b28e9
-        }
25b28e9
+        EndDialog();
25b28e9
     }
25b28e9
     else if (pButton == m_pOKButton)
25b28e9
     {
25b28e9
diff --git a/cui/source/inc/selector.hxx b/cui/source/inc/selector.hxx
25b28e9
index 2f6b194..ad4bfa9 100644
25b28e9
--- a/cui/source/inc/selector.hxx
25b28e9
+++ b/cui/source/inc/selector.hxx
25b28e9
@@ -172,7 +172,7 @@ public:
25b28e9
         { m_pImageProvider = provider; }
25b28e9
 };
25b28e9
 
25b28e9
-class SvxScriptSelectorDialog : public ModelessDialog
25b28e9
+class SvxScriptSelectorDialog : public ModalDialog
25b28e9
 {
25b28e9
     VclPtr<FixedText>                      m_pDialogDescription;
25b28e9
     VclPtr<SvxConfigGroupListBox>          m_pCategories;
d82ce24
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
229f8cb
index eaa222f..871ddd3 100644
d82ce24
--- a/vcl/inc/unx/gtk/gtkframe.hxx
d82ce24
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
229f8cb
@@ -298,6 +298,7 @@ class GtkSalFrame : public SalFrame
d82ce24
     static GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow );
d82ce24
 
d82ce24
     static int m_nFloats;
25b28e9
+    static std::vector<GtkWidget*> m_aGrabWidgetsBeforeShowFloat;
d82ce24
 
d82ce24
     bool isFloatGrabWindow() const
d82ce24
     {
229f8cb
diff --git a/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
229f8cb
index 9798639..b6b60f6 100644
229f8cb
--- a/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
229f8cb
+++ b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
229f8cb
@@ -1012,8 +1012,12 @@ sal_Int16 SAL_CALL SalGtkFilePicker::execute() throw( uno::RuntimeException, std
229f8cb
                             gtk_window_set_title( GTK_WINDOW( dlg ),
229f8cb
                                 OUStringToOString(getResString(FILE_PICKER_TITLE_SAVE ),
229f8cb
                                 RTL_TEXTENCODING_UTF8 ).getStr() );
229f8cb
+#if GTK_CHECK_VERSION(3,0,0)
229f8cb
+                            gtk_window_set_transient_for(GTK_WINDOW(dlg), GTK_WINDOW(m_pDialog));
229f8cb
+#else
229f8cb
                             if (pParent)
229f8cb
                                 gtk_window_set_transient_for(GTK_WINDOW(dlg), pParent);
229f8cb
+#endif
229f8cb
                             RunDialog* pAnotherDialog = new RunDialog(dlg, xToolkit, xDesktop);
229f8cb
                             uno::Reference < awt::XTopWindowListener > xAnotherLifeCycle(pAnotherDialog);
229f8cb
                             btn = pAnotherDialog->run();
229f8cb
diff --git a/vcl/unx/gtk/fpicker/SalGtkPicker.cxx b/vcl/unx/gtk/fpicker/SalGtkPicker.cxx
229f8cb
index 26b2740..06e9550 100644
229f8cb
--- a/vcl/unx/gtk/fpicker/SalGtkPicker.cxx
229f8cb
+++ b/vcl/unx/gtk/fpicker/SalGtkPicker.cxx
229f8cb
@@ -183,8 +183,10 @@ gint RunDialog::run()
229f8cb
     if (mxToolkit.is())
229f8cb
         mxToolkit->removeTopWindowListener(this);
229f8cb
 
229f8cb
+#if !GTK_CHECK_VERSION(3,0,0)
229f8cb
     if (nStatus != 1)   //PLAY
229f8cb
         gtk_widget_hide( mpDialog );
229f8cb
+#endif
229f8cb
 
229f8cb
     return nStatus;
229f8cb
 }
d82ce24
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
229f8cb
index 6363815..1569691 100644
d82ce24
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
d82ce24
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
229f8cb
@@ -106,6 +106,7 @@
d82ce24
 using namespace com::sun::star;
d82ce24
 
d82ce24
 int GtkSalFrame::m_nFloats = 0;
25b28e9
+std::vector<GtkWidget*> GtkSalFrame::m_aGrabWidgetsBeforeShowFloat;
d82ce24
 
d82ce24
 #if defined ENABLE_GMENU_INTEGRATION
d82ce24
 static GDBusConnection* pSessionBus = nullptr;
229f8cb
@@ -834,8 +835,10 @@ GtkSalFrame::~GtkSalFrame()
fe32e4c
 
fe32e4c
     InvalidateGraphics();
fe32e4c
 
fe32e4c
-    if( m_pParent )
fe32e4c
+    if (m_pParent)
fe32e4c
+    {
fe32e4c
         m_pParent->m_aChildren.remove( this );
fe32e4c
+    }
fe32e4c
 
fe32e4c
     getDisplay()->deregisterFrame( this );
fe32e4c
 
229f8cb
@@ -1212,6 +1215,12 @@ void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle )
fe32e4c
         if (!(m_pParent->m_nStyle & SalFrameStyleFlags::PLUG))
fe32e4c
             gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) );
fe32e4c
         m_pParent->m_aChildren.push_back( this );
fe32e4c
+        gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(m_pParent->m_pWindow)), GTK_WINDOW(m_pWindow));
fe32e4c
+    }
fe32e4c
+    else
fe32e4c
+    {
fe32e4c
+        gtk_window_group_add_window(gtk_window_group_new(), GTK_WINDOW(m_pWindow));
fe32e4c
+        g_object_unref(gtk_window_get_group(GTK_WINDOW(m_pWindow)));
fe32e4c
     }
fe32e4c
 
fe32e4c
     InitCommon();
229f8cb
@@ -1447,21 +1456,6 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
d82ce24
                 SetDefaultSize();
d82ce24
             setMinMaxSize();
d82ce24
 
d82ce24
-            if( isFloatGrabWindow() &&
d82ce24
-                m_pParent &&
d82ce24
-                m_nFloats == 0 &&
d82ce24
-                ! getDisplay()->GetCaptureFrame() )
d82ce24
-            {
d82ce24
-                /* #i63086#
d82ce24
-                 * outsmart Metacity's "focus:mouse" mode
d82ce24
-                 * which insists on taking the focus from the document
d82ce24
-                 * to the new float. Grab focus to parent frame BEFORE
d82ce24
-                 * showing the float (cannot grab it to the float
d82ce24
-                 * before show).
d82ce24
-                 */
d82ce24
-                 m_pParent->grabPointer( true, true );
d82ce24
-            }
d82ce24
-
d82ce24
             if( ! bNoActivate && (m_nStyle & SalFrameStyleFlags::TOOLWINDOW) )
d82ce24
                 m_bSetFocusOnMap = true;
d82ce24
 
229f8cb
@@ -1472,6 +1466,13 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
d82ce24
                 m_nFloats++;
d82ce24
                 if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 )
d82ce24
                 {
fe32e4c
+                    GtkWindowGroup *pWindowGroup = gtk_window_get_group(GTK_WINDOW(m_pWindow));
25b28e9
+                    GtkWidget* pGrabWidgetBeforeShowFloat;
fe32e4c
+                    while ((pGrabWidgetBeforeShowFloat = gtk_window_group_get_current_grab(pWindowGroup)))
25b28e9
+                    {
25b28e9
+                        m_aGrabWidgetsBeforeShowFloat.push_back(pGrabWidgetBeforeShowFloat);
25b28e9
+                        gtk_grab_remove(pGrabWidgetBeforeShowFloat);
25b28e9
+                    }
d82ce24
                     grabPointer(true, true);
d82ce24
                     GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this;
d82ce24
                     pKeyboardFrame->grabKeyboard(true);
229f8cb
@@ -1493,6 +1494,9 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
d82ce24
                     GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this;
d82ce24
                     pKeyboardFrame->grabKeyboard(false);
d82ce24
                     grabPointer(false);
25b28e9
+                    for (auto i = m_aGrabWidgetsBeforeShowFloat.rbegin(); i != m_aGrabWidgetsBeforeShowFloat.rend(); ++i)
25b28e9
+                        gtk_grab_add(*i);
25b28e9
+                    m_aGrabWidgetsBeforeShowFloat.clear();
d82ce24
                 }
d82ce24
             }
d82ce24
             gtk_widget_hide( m_pWindow );
229f8cb
@@ -2376,11 +2380,17 @@ const SystemEnvData* GtkSalFrame::GetSystemData() const
fe32e4c
 
fe32e4c
 void GtkSalFrame::SetParent( SalFrame* pNewParent )
fe32e4c
 {
fe32e4c
-    if( m_pParent )
fe32e4c
-        m_pParent->m_aChildren.remove( this );
fe32e4c
+    if (m_pParent)
fe32e4c
+    {
fe32e4c
+        gtk_window_group_remove_window(gtk_window_get_group(GTK_WINDOW(m_pParent->m_pWindow)), GTK_WINDOW(m_pWindow));
fe32e4c
+        m_pParent->m_aChildren.remove(this);
fe32e4c
+    }
fe32e4c
     m_pParent = static_cast<GtkSalFrame*>(pNewParent);
fe32e4c
-    if( m_pParent )
fe32e4c
-        m_pParent->m_aChildren.push_back( this );
fe32e4c
+    if (m_pParent)
fe32e4c
+    {
fe32e4c
+        m_pParent->m_aChildren.push_back(this);
fe32e4c
+        gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(m_pParent->m_pWindow)), GTK_WINDOW(m_pWindow));
fe32e4c
+    }
fe32e4c
     if( ! isChild() )
fe32e4c
         gtk_window_set_transient_for( GTK_WINDOW(m_pWindow),
fe32e4c
                                       (m_pParent && ! m_pParent->isChild(true,false)) ? GTK_WINDOW(m_pParent->m_pWindow) : nullptr
229f8cb
@@ -2431,13 +2441,6 @@ void GtkSalFrame::SetModal(bool bModal)
d82ce24
     if (!m_pWindow)
d82ce24
         return;
d82ce24
     gtk_window_set_modal(GTK_WINDOW(m_pWindow), bModal);
d82ce24
-    if (bModal)
d82ce24
-    {
d82ce24
-        //gtk_window_set_modal bTrue adds a grab, so ungrab here. Quite
d82ce24
-        //possibly we should alternatively call grab_add grab_ungrab on
d82ce24
-        //show/hide of menus ?
d82ce24
-        gtk_grab_remove(m_pWindow);
d82ce24
-    }
d82ce24
 }
d82ce24
 
d82ce24
 gboolean GtkSalFrame::signalTooltipQuery(GtkWidget*, gint /*x*/, gint /*y*/,
d82ce24
-- 
229f8cb
2.7.4
d82ce24