diff --git a/abstract_client.cpp b/abstract_client.cpp
index 44b6fd7f04..4022b4ae13 100644
--- a/abstract_client.cpp
+++ b/abstract_client.cpp
@@ -36,6 +36,9 @@ along with this program. If not, see .
#include
+#include
+#include
+
namespace KWin
{
@@ -1380,4 +1383,82 @@ void AbstractClient::processDecorationMove()
}
}
+bool AbstractClient::processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu)
+{
+ Options::MouseCommand com = Options::MouseNothing;
+ bool active = isActive();
+ if (!wantsInput()) // we cannot be active, use it anyway
+ active = true;
+
+ // check whether it is a double click
+ if (event->button() == Qt::LeftButton) {
+ if (m_decorationDoubleClickTimer.isValid() &&
+ decoration()->titleBar().contains(event->x(), event->y()) &&
+ !m_decorationDoubleClickTimer.hasExpired(QGuiApplication::styleHints()->mouseDoubleClickInterval())) {
+ Workspace::self()->performWindowOperation(this, options->operationTitlebarDblClick());
+ dontMoveResize();
+ m_decorationDoubleClickTimer.invalidate();
+ return false;
+ }
+ m_decorationDoubleClickTimer.invalidate();
+ }
+
+ if (event->button() == Qt::LeftButton)
+ com = active ? options->commandActiveTitlebar1() : options->commandInactiveTitlebar1();
+ else if (event->button() == Qt::MidButton)
+ com = active ? options->commandActiveTitlebar2() : options->commandInactiveTitlebar2();
+ else if (event->button() == Qt::RightButton)
+ com = active ? options->commandActiveTitlebar3() : options->commandInactiveTitlebar3();
+ if (event->button() == Qt::LeftButton
+ && com != Options::MouseOperationsMenu // actions where it's not possible to get the matching
+ && com != Options::MouseMinimize // mouse release event
+ && com != Options::MouseDragTab) {
+ setMoveResizePointerMode(mousePosition());
+ setMoveResizePointerButtonDown(true);
+ setMoveOffset(event->pos());
+ setInvertedMoveOffset(rect().bottomRight() - moveOffset());
+ setUnrestrictedMoveResize(false);
+ startDelayedMoveResize();
+ updateCursor();
+ }
+ // In the new API the decoration may process the menu action to display an inactive tab's menu.
+ // If the event is unhandled then the core will create one for the active window in the group.
+ if (!ignoreMenu || com != Options::MouseOperationsMenu)
+ performMouseCommand(com, event->globalPos());
+ return !( // Return events that should be passed to the decoration in the new API
+ com == Options::MouseRaise ||
+ com == Options::MouseOperationsMenu ||
+ com == Options::MouseActivateAndRaise ||
+ com == Options::MouseActivate ||
+ com == Options::MouseActivateRaiseAndPassClick ||
+ com == Options::MouseActivateAndPassClick ||
+ com == Options::MouseDragTab ||
+ com == Options::MouseNothing);
+}
+
+void AbstractClient::processDecorationButtonRelease(QMouseEvent *event)
+{
+ if (isDecorated()) {
+ if (!event->isAccepted() && decoration()->titleBar().contains(event->pos()) && event->button() == Qt::LeftButton) {
+ m_decorationDoubleClickTimer.start();
+ }
+ }
+
+ if (event->buttons() == Qt::NoButton) {
+ setMoveResizePointerButtonDown(false);
+ stopDelayedMoveResize();
+ if (isMoveResize()) {
+ finishMoveResize(false);
+ setMoveResizePointerMode(mousePosition());
+ }
+ updateCursor();
+ }
+}
+
+
+void AbstractClient::startDecorationDoubleClickTimer()
+{
+ m_decorationDoubleClickTimer.start();
+}
+
}
diff --git a/abstract_client.h b/abstract_client.h
index ea04378b1b..b7d614e17a 100644
--- a/abstract_client.h
+++ b/abstract_client.h
@@ -27,6 +27,8 @@ along with this program. If not, see .
#include
+#include
+
namespace KWayland
{
namespace Server
@@ -506,6 +508,8 @@ public:
void triggerDecorationRepaint();
virtual void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const;
void processDecorationMove();
+ bool processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu = false);
+ void processDecorationButtonRelease(QMouseEvent *event);
// TODO: remove boolean trap
static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, bool active_hack = false);
@@ -813,6 +817,7 @@ protected:
m_decoration = decoration;
}
virtual void destroyDecoration();
+ void startDecorationDoubleClickTimer();
private:
void handlePaletteChange();
@@ -876,6 +881,7 @@ private:
} m_moveResize;
KDecoration2::Decoration *m_decoration = nullptr;
+ QElapsedTimer m_decorationDoubleClickTimer;
static bool s_haveResizeEffect;
diff --git a/client.cpp b/client.cpp
index 972405bae5..f927a40668 100644
--- a/client.cpp
+++ b/client.cpp
@@ -2141,32 +2141,6 @@ bool Client::belongsToSameApplication(const AbstractClient *other, bool active_h
return Client::belongToSameApplication(this, c2, active_hack);
}
-bool Client::processDecorationButtonPress(QMouseEvent *event)
-{
- return processDecorationButtonPress(qtToX11Button(event->button()), 0,
- event->x(), event->y(),
- event->globalX(), event->globalY());
-}
-
-void Client::processDecorationButtonRelease(QMouseEvent *event)
-{
- if (isDecorated()) {
- if (!event->isAccepted() && decoration()->titleBar().contains(event->pos()) && event->button() == Qt::LeftButton) {
- m_decorationDoubleClickTimer.start();
- }
- }
-
- if (event->buttons() == Qt::NoButton) {
- setMoveResizePointerButtonDown(false);
- stopDelayedMoveResize();
- if (isMoveResize()) {
- finishMoveResize(false);
- setMoveResizePointerMode(mousePosition());
- }
- updateCursor();
- }
-}
-
void Client::updateTabGroupStates(TabGroup::States states)
{
if (auto t = tabGroup()) {
diff --git a/client.h b/client.h
index c1cb126e26..e442df98e3 100644
--- a/client.h
+++ b/client.h
@@ -162,8 +162,6 @@ public:
bool windowEvent(xcb_generic_event_t *e);
void syncEvent(xcb_sync_alarm_notify_event_t* e);
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
- bool processDecorationButtonPress(QMouseEvent *event);
- void processDecorationButtonRelease(QMouseEvent *event);
bool manage(xcb_window_t w, bool isMapped);
void releaseWindow(bool on_shutdown = false);
@@ -401,8 +399,6 @@ private:
bool buttonReleaseEvent(xcb_window_t w, int button, int state, int x, int y, int x_root, int y_root);
bool motionNotifyEvent(xcb_window_t w, int state, int x, int y, int x_root, int y_root);
- bool processDecorationButtonPress(int button, int state, int x, int y, int x_root, int y_root,
- bool ignoreMenu = false);
Client* findAutogroupCandidate() const;
protected:
@@ -548,7 +544,6 @@ private:
Xcb::Window m_wrapper;
Xcb::Window m_frame;
QPointer m_decoratedClient;
- QElapsedTimer m_decorationDoubleClickTimer;
QStringList activityList;
int m_activityUpdatesBlocked;
bool m_blockedActivityUpdatesRequireTransients;
diff --git a/events.cpp b/events.cpp
index 6324d15032..ee106f329c 100644
--- a/events.cpp
+++ b/events.cpp
@@ -1168,7 +1168,9 @@ bool Client::buttonPressEvent(xcb_window_t w, int button, int state, int x, int
x = x_root - geometry().x();
y = y_root - geometry().y();
// New API processes core events FIRST and only passes unused ones to the decoration
- return processDecorationButtonPress(button, state, x, y, x_root, y_root, true);
+ QMouseEvent ev(QMouseEvent::MouseButtonPress, QPoint(x, y), QPoint(x_root, y_root),
+ x11ToQtMouseButton(button), x11ToQtMouseButtons(state), Qt::KeyboardModifiers());
+ return processDecorationButtonPress(&ev, true);
}
if (w == frameId() && isDecorated()) {
if (button >= 4 && button <= 7) {
@@ -1200,7 +1202,7 @@ bool Client::buttonPressEvent(xcb_window_t w, int button, int state, int x, int
event.setAccepted(false);
QCoreApplication::sendEvent(decoration(), &event);
if (!event.isAccepted()) {
- processDecorationButtonPress(button, state, x, y, x_root, y_root);
+ processDecorationButtonPress(&event);
}
}
return true;
@@ -1208,63 +1210,6 @@ bool Client::buttonPressEvent(xcb_window_t w, int button, int state, int x, int
return true;
}
-
-// this function processes button press events only after decoration decides not to handle them,
-// unlike buttonPressEvent(), which (when the window is decoration) filters events before decoration gets them
-bool Client::processDecorationButtonPress(int button, int /*state*/, int x, int y, int x_root, int y_root,
- bool ignoreMenu)
-{
- Options::MouseCommand com = Options::MouseNothing;
- bool active = isActive();
- if (!wantsInput()) // we cannot be active, use it anyway
- active = true;
-
- // check whether it is a double click
- if (button == XCB_BUTTON_INDEX_1) {
- if (m_decorationDoubleClickTimer.isValid() &&
- decoration()->titleBar().contains(x, y) &&
- !m_decorationDoubleClickTimer.hasExpired(QGuiApplication::styleHints()->mouseDoubleClickInterval())) {
- Workspace::self()->performWindowOperation(this, options->operationTitlebarDblClick());
- dontMoveResize();
- m_decorationDoubleClickTimer.invalidate();
- return false;
- }
- m_decorationDoubleClickTimer.invalidate();
- }
-
- if (button == XCB_BUTTON_INDEX_1)
- com = active ? options->commandActiveTitlebar1() : options->commandInactiveTitlebar1();
- else if (button == XCB_BUTTON_INDEX_2)
- com = active ? options->commandActiveTitlebar2() : options->commandInactiveTitlebar2();
- else if (button == XCB_BUTTON_INDEX_3)
- com = active ? options->commandActiveTitlebar3() : options->commandInactiveTitlebar3();
- if (button == XCB_BUTTON_INDEX_1
- && com != Options::MouseOperationsMenu // actions where it's not possible to get the matching
- && com != Options::MouseMinimize // mouse release event
- && com != Options::MouseDragTab) {
- setMoveResizePointerMode(mousePosition());
- setMoveResizePointerButtonDown(true);
- setMoveOffset(QPoint(x/* - padding_left*/, y/* - padding_top*/));
- setInvertedMoveOffset(rect().bottomRight() - moveOffset());
- setUnrestrictedMoveResize(false);
- startDelayedMoveResize();
- updateCursor();
- }
- // In the new API the decoration may process the menu action to display an inactive tab's menu.
- // If the event is unhandled then the core will create one for the active window in the group.
- if (!ignoreMenu || com != Options::MouseOperationsMenu)
- performMouseCommand(com, QPoint(x_root, y_root));
- return !( // Return events that should be passed to the decoration in the new API
- com == Options::MouseRaise ||
- com == Options::MouseOperationsMenu ||
- com == Options::MouseActivateAndRaise ||
- com == Options::MouseActivate ||
- com == Options::MouseActivateRaiseAndPassClick ||
- com == Options::MouseActivateAndPassClick ||
- com == Options::MouseDragTab ||
- com == Options::MouseNothing);
-}
-
// return value matters only when filtering events before decoration gets them
bool Client::buttonReleaseEvent(xcb_window_t w, int button, int state, int x, int y, int x_root, int y_root)
{
@@ -1280,7 +1225,7 @@ bool Client::buttonReleaseEvent(xcb_window_t w, int button, int state, int x, in
event.setAccepted(false);
QCoreApplication::sendEvent(decoration(), &event);
if (!event.isAccepted() && decoration()->titleBar().contains(x, y) && button == XCB_BUTTON_INDEX_1) {
- m_decorationDoubleClickTimer.start();
+ startDecorationDoubleClickTimer();
}
}
}