From 5de55b61e7d8a75a01cafef2d5b4754f69ab68e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 3 Dec 2015 16:40:27 +0100 Subject: [PATCH] Move processDecorationButton(Press|Release) to AbstractClient This also requires to move m_decorationDoubleClickTimer and reworking a bit how the x11 events are passed to processDecorationButtonPress. --- abstract_client.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++ abstract_client.h | 6 ++++ client.cpp | 26 --------------- client.h | 5 --- events.cpp | 65 +++--------------------------------- 5 files changed, 92 insertions(+), 91 deletions(-) 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(); } } }