[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-1+backports' - 3 commits - include/vcl sfx2/source vcl/inc vcl/source vcl/unx
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Tue Sep 17 14:15:13 UTC 2019
include/vcl/event.hxx | 2
include/vcl/window.hxx | 1
sfx2/source/view/frame2.cxx | 34 +++++----
vcl/inc/salframe.hxx | 4 +
vcl/source/window/dialog.cxx | 10 +-
vcl/source/window/window.cxx | 5 +
vcl/unx/gtk3/gtk3gtkinst.cxx | 149 ++++++++++++++++++++++++++++++++++++++++---
7 files changed, 175 insertions(+), 30 deletions(-)
New commits:
commit 009a9ebb7cc0de49cd51b11995cf60d0ca45e7d3
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri Jun 14 09:18:44 2019 +0100
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Tue Sep 17 16:14:36 2019 +0200
disable 'quit' menu entry when modal dialog waiting response
Traditionally when a modal dialog is active, the quit menu entry of all
LibreOffice toplevel frames, not just those which are themselves modal, is get
disabled.
This has come unstuck because its implemented by dialogs emitting
MouseNotifyEvent::[END]EXECUTEDIALOG on its parent, and SfxFrameWindow_Impl
listening for that event. But if the dialog parent is the toplevel parent of
SfxFrameWindow_Impl then it doesn't get seen by the SfxFrameWindow_Impl child.
Reviewed-on: https://gerrit.libreoffice.org/73975
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit 252239ae30313142195b3da81aea45a89b2d6674)
Conflicts:
include/vcl/event.hxx
include/vcl/window.hxx
sfx2/source/view/frame2.cxx
vcl/source/window/dialog.cxx
vcl/source/window/window.cxx
Change-Id: I0c4a5472d16d9169e68f6b0c230d039f1119489a
Reviewed-on: https://gerrit.libreoffice.org/79040
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
Tested-by: Michael Weghorn <m.weghorn at posteo.de>
diff --git a/include/vcl/event.hxx b/include/vcl/event.hxx
index 050e7199cc45..3a5122eb941a 100644
--- a/include/vcl/event.hxx
+++ b/include/vcl/event.hxx
@@ -290,8 +290,6 @@ enum class MouseNotifyEvent
DESTROY = 9,
INPUTENABLE = 10,
INPUTDISABLE = 11,
- EXECUTEDIALOG = 100,
- ENDEXECUTEDIALOG = 101
};
class VCL_DLLPUBLIC NotifyEvent
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 3a3ea99d2c0f..f0eaaff573f1 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1605,6 +1605,7 @@ public:
virtual bool IsChart() const { return false; }
void SetHelpHdl(const Link<vcl::Window&, bool>& rLink);
+ void SetModalHierarchyHdl(const Link<bool, void>& rLink);
};
}
diff --git a/sfx2/source/view/frame2.cxx b/sfx2/source/view/frame2.cxx
index 6fc3cff26a7d..e003d9697358 100644
--- a/sfx2/source/view/frame2.cxx
+++ b/sfx2/source/view/frame2.cxx
@@ -58,9 +58,9 @@ using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;
using ::com::sun::star::frame::XComponentLoader;
-
class SfxFrameWindow_Impl : public vcl::Window
{
+ DECL_LINK(ModalHierarchyHdl, bool, void);
public:
SfxFrame* pFrame;
@@ -72,13 +72,21 @@ public:
virtual bool EventNotify( NotifyEvent& rEvt ) override;
virtual void Resize() override;
virtual void GetFocus() override;
+ virtual void dispose() override;
void DoResize();
};
-SfxFrameWindow_Impl::SfxFrameWindow_Impl( SfxFrame* pF, vcl::Window& i_rContainerWindow )
- : Window( &i_rContainerWindow, WB_BORDER | WB_CLIPCHILDREN | WB_NODIALOGCONTROL | WB_3DLOOK )
- , pFrame( pF )
+SfxFrameWindow_Impl::SfxFrameWindow_Impl(SfxFrame* pF, vcl::Window& i_rContainerWindow)
+ : Window(&i_rContainerWindow, WB_BORDER | WB_CLIPCHILDREN | WB_NODIALOGCONTROL | WB_3DLOOK)
+ , pFrame(pF)
+{
+ i_rContainerWindow.SetModalHierarchyHdl(LINK(this, SfxFrameWindow_Impl, ModalHierarchyHdl));
+}
+
+void SfxFrameWindow_Impl::dispose()
{
+ GetParent()->SetModalHierarchyHdl(Link<bool, void>());
+ vcl::Window::dispose();
}
void SfxFrameWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
@@ -116,20 +124,18 @@ bool SfxFrameWindow_Impl::EventNotify( NotifyEvent& rNEvt )
if ( pView->GetViewShell()->KeyInput( *rNEvt.GetKeyEvent() ) )
return true;
}
- else if ( rNEvt.GetType() == MouseNotifyEvent::EXECUTEDIALOG /*|| rNEvt.GetType() == MouseNotifyEvent::INPUTDISABLE*/ )
- {
- pView->SetModalMode( true );
- return true;
- }
- else if ( rNEvt.GetType() == MouseNotifyEvent::ENDEXECUTEDIALOG /*|| rNEvt.GetType() == MouseNotifyEvent::INPUTENABLE*/ )
- {
- pView->SetModalMode( false );
- return true;
- }
return Window::EventNotify( rNEvt );
}
+IMPL_LINK(SfxFrameWindow_Impl, ModalHierarchyHdl, bool, bSetModal, void)
+{
+ SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
+ if (!pView || !pView->GetObjectShell())
+ return;
+ pView->SetModalMode(bSetModal);
+}
+
bool SfxFrameWindow_Impl::PreNotify( NotifyEvent& rNEvt )
{
MouseNotifyEvent nType = rNEvt.GetType();
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index e2662d415fc2..06d8b1835c03 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -108,6 +108,7 @@ private:
// the VCL window corresponding to this frame
VclPtr<vcl::Window> m_pWindow;
SALFRAMEPROC m_pProc;
+ Link<bool, void> m_aModalHierarchyHdl;
protected:
mutable std::unique_ptr<weld::Window> m_xFrameWeld;
public:
@@ -273,6 +274,9 @@ public:
// returns the instance set
vcl::Window* GetWindow() const { return m_pWindow; }
+ void SetModalHierarchyHdl(const Link<bool, void>& rLink) { m_aModalHierarchyHdl = rLink; }
+ void NotifyModalHierarchy(bool bModal) { m_aModalHierarchyHdl.Call(bModal); }
+
// Call the callback set; this sometimes necessary for implementation classes
// that should not know more than necessary about the SalFrame implementation
// (e.g. input methods, printer update handlers).
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index a1d8cf1e6a6c..ef7dfe73c57e 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -913,11 +913,13 @@ bool Dialog::ImplStartExecuteModal()
pSVData->maWinData.mpCaptureWin->ReleaseMouse();
EnableInput();
+
if ( GetParent() )
{
- NotifyEvent aNEvt( MouseNotifyEvent::EXECUTEDIALOG, this );
- GetParent()->CompatNotify( aNEvt );
+ SalFrame* pFrame = GetParent()->ImplGetFrame();
+ pFrame->NotifyModalHierarchy(true);
}
+
mbInExecute = true;
// no real modality in LibreOfficeKit
if (!bKitActive)
@@ -1119,8 +1121,8 @@ void Dialog::EndDialog( long nResult )
Hide();
if ( GetParent() )
{
- NotifyEvent aNEvt( MouseNotifyEvent::ENDEXECUTEDIALOG, this );
- GetParent()->CompatNotify( aNEvt );
+ SalFrame* pFrame = GetParent()->ImplGetFrame();
+ pFrame->NotifyModalHierarchy(false);
}
mpDialogImpl->mnResult = nResult;
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 3d7a5323227f..d15181288cf2 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1760,6 +1760,11 @@ void Window::ImplNewInputContext()
pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
}
+void Window::SetModalHierarchyHdl(const Link<bool, void>& rLink)
+{
+ ImplGetFrame()->SetModalHierarchyHdl(rLink);
+}
+
void Window::doLazyDelete()
{
SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
commit 330cf24731919c049db1ad18697306dc046de65a
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Sep 9 14:09:37 2018 +0100
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Tue Sep 17 16:14:33 2019 +0200
silence bogus -Wmaybe-uninitialized
Change-Id: I702b4818f05a606da30a643e13bfcd2c98ba412a
Reviewed-on: https://gerrit.libreoffice.org/60215
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit b829325fb407250849d9508ed32176b08006dd0a)
Reviewed-on: https://gerrit.libreoffice.org/79039
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
Tested-by: Michael Weghorn <m.weghorn at posteo.de>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 4cb75e50f695..955705cdc72a 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1813,7 +1813,7 @@ public:
}
virtual void set_mode(VclSizeGroupMode eVclMode) override
{
- GtkSizeGroupMode eGtkMode;
+ GtkSizeGroupMode eGtkMode(GTK_SIZE_GROUP_NONE);
switch (eVclMode)
{
case VclSizeGroupMode::NONE:
commit 65c72516c9e3b915e123d6c715e86ef38ac46374
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Nov 27 10:18:52 2018 +0000
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Tue Sep 17 16:14:27 2019 +0200
enable hiding gtk dialogs without ending their dialog loop
we need this to support reshowing dialog after an intermediate
range selection dialog executes
Reviewed-on: https://gerrit.libreoffice.org/64100
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit 471d6c3653b8b8006db022c5d94af7503adfdc56)
Conflicts:
vcl/unx/gtk3/gtk3gtkinst.cxx
Change-Id: Ib6575e5d852bd1d29cc1a791a5dc2c19949b67a0
Reviewed-on: https://gerrit.libreoffice.org/79038
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
Tested-by: Michael Weghorn <m.weghorn at posteo.de>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 384f1d411e4d..4cb75e50f695 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -2029,10 +2029,117 @@ namespace
}
}
+struct DialogRunner
+{
+ GtkDialog *m_pDialog;
+ gint m_nResponseId;
+ GMainLoop *m_pLoop;
+ VclPtr<vcl::Window> m_xFrameWindow;
+
+ DialogRunner(GtkDialog* pDialog)
+ : m_pDialog(pDialog)
+ , m_nResponseId(GTK_RESPONSE_NONE)
+ , m_pLoop(nullptr)
+ {
+ GtkWindow* pParent = gtk_window_get_transient_for(GTK_WINDOW(m_pDialog));
+ GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(pParent);
+ m_xFrameWindow = pFrame ? pFrame->GetWindow() : nullptr;
+ }
+
+ bool loop_is_running() const
+ {
+ return m_pLoop && g_main_loop_is_running(m_pLoop);
+ }
+
+ void loop_quit()
+ {
+ if (g_main_loop_is_running(m_pLoop))
+ g_main_loop_quit(m_pLoop);
+ }
+
+ static void signal_response(GtkDialog*, gint nResponseId, gpointer data)
+ {
+ DialogRunner* pThis = static_cast<DialogRunner*>(data);
+ pThis->m_nResponseId = nResponseId;
+ pThis->loop_quit();
+ }
+
+ static gboolean signal_delete(GtkDialog*, GdkEventAny*, gpointer data)
+ {
+ DialogRunner* pThis = static_cast<DialogRunner*>(data);
+ pThis->loop_quit();
+ return true; /* Do not destroy */
+ }
+
+ static void signal_destroy(GtkDialog*, gpointer data)
+ {
+ DialogRunner* pThis = static_cast<DialogRunner*>(data);
+ pThis->loop_quit();
+ }
+
+ void inc_modal_count()
+ {
+ if (m_xFrameWindow)
+ m_xFrameWindow->IncModalCount();
+ }
+
+ void dec_modal_count()
+ {
+ if (m_xFrameWindow)
+ m_xFrameWindow->DecModalCount();
+ }
+
+ // same as gtk_dialog_run except that unmap doesn't auto-respond
+ // so we can hide the dialog and restore it without a response getting
+ // triggered
+ gint run()
+ {
+ g_object_ref(m_pDialog);
+
+ inc_modal_count();
+
+ bool bWasModal = gtk_window_get_modal(GTK_WINDOW(m_pDialog));
+ if (!bWasModal)
+ gtk_window_set_modal(GTK_WINDOW(m_pDialog), true);
+
+ if (!gtk_widget_get_visible(GTK_WIDGET(m_pDialog)))
+ gtk_widget_show(GTK_WIDGET(m_pDialog));
+
+ gulong nSignalResponseId = g_signal_connect(m_pDialog, "response", G_CALLBACK(signal_response), this);
+ gulong nSignalDeleteId = g_signal_connect(m_pDialog, "delete-event", G_CALLBACK(signal_delete), this);
+ gulong nSignalDestroyId = g_signal_connect(m_pDialog, "destroy", G_CALLBACK(signal_destroy), this);
+
+ m_pLoop = g_main_loop_new(nullptr, false);
+ m_nResponseId = GTK_RESPONSE_NONE;
+
+ gdk_threads_leave();
+ g_main_loop_run(m_pLoop);
+ gdk_threads_enter();
+
+ g_main_loop_unref(m_pLoop);
+
+ m_pLoop = nullptr;
+
+ if (!bWasModal)
+ gtk_window_set_modal(GTK_WINDOW(m_pDialog), false);
+
+ g_signal_handler_disconnect(m_pDialog, nSignalResponseId);
+ g_signal_handler_disconnect(m_pDialog, nSignalDeleteId);
+ g_signal_handler_disconnect(m_pDialog, nSignalDestroyId);
+
+ dec_modal_count();
+
+ g_object_unref(m_pDialog);
+
+ return m_nResponseId;
+ }
+};
+
class GtkInstanceDialog : public GtkInstanceWindow, public virtual weld::Dialog
{
private:
GtkDialog* m_pDialog;
+ DialogRunner m_aDialogRun;
std::shared_ptr<weld::DialogController> m_xDialogController;
std::function<void(sal_Int32)> m_aFunc;
gulong m_nCloseSignalId;
@@ -2082,10 +2189,12 @@ private:
m_aFunc = nullptr;
m_xDialogController.reset();
}
+
public:
GtkInstanceDialog(GtkDialog* pDialog, bool bTakeOwnership)
: GtkInstanceWindow(GTK_WINDOW(pDialog), bTakeOwnership)
, m_pDialog(pDialog)
+ , m_aDialogRun(pDialog)
, m_nCloseSignalId(g_signal_connect(m_pDialog, "close", G_CALLBACK(signalClose), this))
, m_nResponseSignalId(0)
{
@@ -2115,16 +2224,9 @@ public:
{
sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog)));
int ret;
- GtkWindow* pParent = gtk_window_get_transient_for(GTK_WINDOW(m_pDialog));
- GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(pParent);
- vcl::Window* pFrameWindow = pFrame ? pFrame->GetWindow() : nullptr;
while (true)
{
- if (pFrameWindow)
- pFrameWindow->IncModalCount();
- ret = gtk_dialog_run(m_pDialog);
- if (pFrameWindow)
- pFrameWindow->DecModalCount();
+ ret = m_aDialogRun.run();
if (ret == GTK_RESPONSE_HELP)
{
help();
@@ -2139,6 +2241,34 @@ public:
return GtkToVcl(ret);
}
+ virtual void hide() override
+ {
+ if (!gtk_widget_get_visible(m_pWidget))
+ return;
+ gtk_widget_hide(m_pWidget);
+ // if we hide the dialog while its running, then decrement the parent LibreOffice window
+ // modal count, we expect the dialog to restored while its running and match up with
+ // the inc_modal_count of show()
+ //
+ // This hide while running case is for the calc/chart dialogs which put
+ // up an extra range chooser dialog, hides the original, the user can
+ // select a range of cells and on completion the original dialog is
+ // restored
+ if (m_aDialogRun.loop_is_running())
+ m_aDialogRun.dec_modal_count();
+ }
+
+ virtual void show() override
+ {
+ if (gtk_widget_get_visible(m_pWidget))
+ return;
+ sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog)));
+ gtk_widget_show(m_pWidget);
+ // see hide comment
+ if (m_aDialogRun.loop_is_running())
+ m_aDialogRun.inc_modal_count();
+ }
+
static int VclToGtk(int nResponse)
{
if (nResponse == RET_OK)
@@ -2359,7 +2489,6 @@ static void crippled_viewport_class_init(GtkViewportClass *klass)
/* GObject signals */
o_class->set_property = crippled_viewport_set_property;
o_class->get_property = crippled_viewport_get_property;
-// o_class->finalize = gtk_tree_view_finalize;
/* Properties */
g_object_class_override_property(o_class, PROP_HADJUSTMENT, "hadjustment");
More information about the Libreoffice-commits
mailing list