Commit 338772ca authored by David Redondo's avatar David Redondo 🏎
Browse files

Open Klipper under mouse also on wayland

On Wayland if Plasma had no focus when the shortcut was invoked
- the menu window is  created as toplevel because it has no parent and
  there is no current focusWindow
- the application can't know the currrent cursor position
We use a newly introduced request on plasma_surface to open under the cursor.
As it can only be called before mapping a buffer to a surface, the menu is hidden
before being shown again.
BUG:436249
FIXED-IN:5.25
parent c6b539eb
......@@ -47,6 +47,7 @@ target_link_libraries(libklipper_common_static
KF5::WindowSystem
KF5::WidgetsAddons
KF5::XmlGui
KF5::WaylandClient
${ZLIB_LIBRARY})
if (X11_FOUND)
target_link_libraries(libklipper_common_static XCB::XCB)
......
......@@ -27,6 +27,10 @@
#include <KNotification>
#include <KSystemClipboard>
#include <KToggleAction>
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/plasmashell.h>
#include <KWayland/Client/registry.h>
#include <KWayland/Client/surface.h>
#include <KWindowSystem>
#include "configdialog.h"
......@@ -113,6 +117,7 @@ Klipper::Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mo
, m_config(config)
, m_pendingContentsCheck(false)
, m_mode(mode)
, m_plasmashell(nullptr)
{
if (m_mode == KlipperMode::Standalone) {
setenv("KSNI_NO_DBUSMENU", "1", 1);
......@@ -249,6 +254,18 @@ Klipper::Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mo
m_notification->setHint(QStringLiteral("desktop-entry"), QStringLiteral("org.kde.klipper"));
}
});
if (KWindowSystem::isPlatformWayland()) {
auto registry = new KWayland::Client::Registry(this);
auto connection = KWayland::Client::ConnectionThread::fromApplication(qGuiApp);
connect(registry, &KWayland::Client::Registry::plasmaShellAnnounced, this, [registry, this](quint32 name, quint32 version) {
if (!m_plasmashell) {
m_plasmashell = registry->createPlasmaShell(name, version);
}
});
registry->create(connection);
registry->setup();
}
}
Klipper::~Klipper()
......@@ -384,10 +401,26 @@ void Klipper::saveSettings() const
void Klipper::showPopupMenu(QMenu *menu)
{
Q_ASSERT(menu != nullptr);
if (m_plasmashell) {
menu->hide();
menu->windowHandle()->installEventFilter(this);
}
menu->popup(QCursor::pos());
}
bool Klipper::eventFilter(QObject *filtered, QEvent *event)
{
const bool ret = QObject::eventFilter(filtered, event);
auto menuWindow = qobject_cast<QWindow *>(filtered);
if (menuWindow && event->type() == QEvent::Expose && menuWindow->isVisible()) {
auto surface = KWayland::Client::Surface::fromWindow(menuWindow);
auto plasmaSurface = m_plasmashell->createSurface(surface, menuWindow);
plasmaSurface->openUnderCursor();
menuWindow->removeEventFilter(this);
}
return ret;
}
bool Klipper::loadHistory()
{
static const char failed_load_warning[] = "Failed to load history resource. Clipboard history cannot be read.";
......
......@@ -31,6 +31,14 @@ class HistoryItem;
class KNotification;
class KSystemClipboard;
namespace KWayland
{
namespace Client
{
class PlasmaShell;
}
}
enum class KlipperMode {
Standalone,
DataEngine,
......@@ -65,6 +73,8 @@ public:
Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mode = KlipperMode::Standalone);
~Klipper() override;
bool eventFilter(QObject *object, QEvent *event) override;
/**
* Get clipboard history (the "document")
*/
......@@ -223,4 +233,5 @@ private:
KlipperMode m_mode;
QTimer *m_saveFileTimer = nullptr;
QPointer<KNotification> m_notification;
KWayland::Client::PlasmaShell *m_plasmashell;
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment