[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: add DismissPopupEventFilter from KDE Plasma
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Fri May 12 16:34:33 UTC 2023
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
466f7b7b by Fatih Uzunoglu at 2023-05-12T16:02:36+00:00
qt: add DismissPopupEventFilter from KDE Plasma
- - - - -
46e494fc by Fatih Uzunoglu at 2023-05-12T16:02:36+00:00
qt: use DismissPopupEventFilter
- - - - -
5 changed files:
- modules/gui/qt/Makefile.am
- modules/gui/qt/meson.build
- modules/gui/qt/qt.cpp
- + modules/gui/qt/util/dismiss_popup_event_filter.cpp
- + modules/gui/qt/util/dismiss_popup_event_filter.hpp
Changes:
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -326,6 +326,8 @@ libqt_plugin_la_SOURCES = \
gui/qt/util/effects_image_provider.hpp \
gui/qt/util/qsgroundedrectangularimagenode.cpp \
gui/qt/util/qsgroundedrectangularimagenode.hpp \
+ gui/qt/util/dismiss_popup_event_filter.cpp \
+ gui/qt/util/dismiss_popup_event_filter.hpp \
gui/qt/widgets/native/animators.cpp \
gui/qt/widgets/native/animators.hpp \
gui/qt/widgets/native/customwidgets.cpp gui/qt/widgets/native/customwidgets.hpp \
@@ -511,6 +513,7 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/util/vlctick.moc.cpp \
gui/qt/util/qmlinputitem.moc.cpp \
gui/qt/util/qsgroundedrectangularimagenode.moc.cpp \
+ gui/qt/util/dismiss_popup_event_filter.moc.cpp \
gui/qt/widgets/native/animators.moc.cpp \
gui/qt/widgets/native/csdthemeimage.moc.cpp \
gui/qt/widgets/native/customwidgets.moc.cpp \
=====================================
modules/gui/qt/meson.build
=====================================
@@ -137,6 +137,7 @@ moc_headers = files(
'util/vlctick.hpp',
'util/qmlinputitem.hpp',
'util/qsgroundedrectangularimagenode.hpp',
+ 'util/dismiss_popup_event_filter.hpp',
'widgets/native/animators.hpp',
'widgets/native/csdthemeimage.hpp',
'widgets/native/customwidgets.hpp',
@@ -453,6 +454,8 @@ some_sources = files(
'util/effects_image_provider.hpp',
'util/qsgroundedrectangularimagenode.cpp',
'util/qsgroundedrectangularimagenode.hpp',
+ 'util/dismiss_popup_event_filter.cpp',
+ 'util/dismiss_popup_event_filter.hpp',
'widgets/native/animators.cpp',
'widgets/native/animators.hpp',
'widgets/native/customwidgets.cpp',
=====================================
modules/gui/qt/qt.cpp
=====================================
@@ -67,6 +67,7 @@ extern "C" char **environ;
#include "dialogs/extensions/extensions_manager.hpp" /* Extensions manager */
#include "dialogs/plugins/addons_manager.hpp" /* Addons manager */
#include "dialogs/help/help.hpp" /* Launch Update */
+#include "util/dismiss_popup_event_filter.hpp"
#include "maininterface/compositor.hpp"
#include <QVector>
@@ -822,14 +823,18 @@ static void *Thread( void *obj )
/* Check window type from the Qt platform back-end */
bool known_type = true;
- QString platform = app.platformName();
- if( platform == qfu("xcb") )
+ const QString& platform = app.platformName();
+ if( platform == QLatin1String("xcb") )
p_intf->voutWindowType = VLC_WINDOW_TYPE_XID;
- else if( platform == qfu("wayland") || platform == qfu("wayland-egl") )
+ else if( platform == QLatin1String("wayland") || platform == QLatin1String("wayland-egl") ) {
p_intf->voutWindowType = VLC_WINDOW_TYPE_WAYLAND;
- else if( platform == qfu("windows") )
+
+ // Workaround for popup widgets not closing on mouse press on wayland:
+ app.installEventFilter(new DismissPopupEventFilter(&app));
+ }
+ else if( platform == QLatin1String("windows") )
p_intf->voutWindowType = VLC_WINDOW_TYPE_HWND;
- else if( platform == qfu("cocoa" ) )
+ else if( platform == QLatin1String("cocoa") )
p_intf->voutWindowType = VLC_WINDOW_TYPE_NSOBJECT;
else
{
=====================================
modules/gui/qt/util/dismiss_popup_event_filter.cpp
=====================================
@@ -0,0 +1,69 @@
+/*
+ SPDX-FileCopyrightText: 2008 Aaron Seigo <aseigo at kde.org>
+ SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas at kde.org>
+ SPDX-FileCopyrightText: 2013 Ivan Cukic <ivan.cukic at kde.org>
+ SPDX-FileCopyrightText: 2013 Marco Martin <mart at kde.org>
+
+ SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+/*
+ This file is part of the KDE Plasma project.
+ Origin: plasma-workspace/shell/shellcorona.cpp
+*/
+
+#include "dismiss_popup_event_filter.hpp"
+
+#include <QMouseEvent>
+#include <QWidget>
+#include <QWindow>
+#include <QApplication>
+
+DismissPopupEventFilter::DismissPopupEventFilter(QObject *parent)
+ : QObject{parent}
+{
+
+}
+
+bool DismissPopupEventFilter::eventFilter(QObject *watched, QEvent *event)
+{
+ if (event->type() == QEvent::MouseButtonPress) {
+ if (m_filterMouseEvents) {
+ // Eat events until all mouse buttons are released.
+ return true;
+ }
+
+ QWidget *popup = QApplication::activePopupWidget();
+ if (!popup) {
+ return false;
+ }
+
+ QWindow *window = qobject_cast<QWindow *>(watched);
+ if (popup->windowHandle() == window) {
+ // The popup window handles mouse events before the widget.
+ return false;
+ }
+
+ QWidget *widget = qobject_cast<QWidget *>(watched);
+ if (widget) {
+ // Let the popup widget handle the mouse press event.
+ return false;
+ }
+
+ popup->close();
+ m_filterMouseEvents = true;
+ return true;
+
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ if (m_filterMouseEvents) {
+ // Eat events until all mouse buttons are released.
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+ if (mouseEvent->buttons() == Qt::NoButton) {
+ m_filterMouseEvents = false;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
=====================================
modules/gui/qt/util/dismiss_popup_event_filter.hpp
=====================================
@@ -0,0 +1,66 @@
+/*
+ SPDX-FileCopyrightText: 2008 Aaron Seigo <aseigo at kde.org>
+ SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas at kde.org>
+ SPDX-FileCopyrightText: 2013 Ivan Cukic <ivan.cukic at kde.org>
+ SPDX-FileCopyrightText: 2013 Marco Martin <mart at kde.org>
+
+ SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+/*
+ This file is part of the KDE Plasma project.
+ Origin: plasma-workspace/shell/shellcorona.cpp
+*/
+
+#ifndef DISMISSPOPUPEVENTFILTER_HPP
+#define DISMISSPOPUPEVENTFILTER_HPP
+
+#include <QObject>
+
+/**
+ * @internal
+ *
+ * The DismissPopupEventFilter class monitors mouse button press events and
+ * when needed dismisses the active popup widget.
+ *
+ * plasmashell uses both QtQuick and QtWidgets under a single roof, QtQuick is
+ * used for most of things, while QtWidgets is used for things such as context
+ * menus, etc.
+ *
+ * If user clicks outside a popup window, it's expected that the popup window
+ * will be closed. On X11, it's achieved by establishing both a keyboard grab
+ * and a pointer grab. But on Wayland, you can't grab keyboard or pointer. If
+ * user clicks a surface of another app, the compositor will dismiss the popup
+ * surface. However, if user clicks some surface of the same application, the
+ * popup surface won't be dismissed, it's up to the application to decide
+ * whether the popup must be closed. In 99% cases, it must.
+ *
+ * Qt has some code that dismisses the active popup widget if another window
+ * of the same app has been clicked. But, that code works only if the
+ * application uses solely Qt widgets. See QTBUG-83972. For plasma it doesn't
+ * work, because as we said previously, it uses both Qt Quick and Qt Widgets.
+ *
+ * Ideally, this bug needs to be fixed upstream, but given that it'll involve
+ * major changes in Qt, the chances of it being fixed any time soon are slim.
+ *
+ * In order to work around the popup dismissal bug, we install an event filter
+ * that monitors Qt::MouseButtonPress events. If it happens that user has
+ * clicked outside an active popup widget, that popup will be closed. This
+ * event filter is not needed on X11!
+ */
+class DismissPopupEventFilter : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit DismissPopupEventFilter(QObject *parent = nullptr);
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event) override;
+
+private:
+ bool m_filterMouseEvents = false;
+
+};
+
+#endif // DISMISSPOPUPEVENTFILTER_HPP
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e2d4c69d79ed8f19b4bdd9cee7ed8227400842d3...46e494fcc31b0a433d609b5d96c08cf37b0223c7
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e2d4c69d79ed8f19b4bdd9cee7ed8227400842d3...46e494fcc31b0a433d609b5d96c08cf37b0223c7
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list