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.
This commit is contained in:
parent
38d3346faa
commit
5de55b61e7
5 changed files with 92 additions and 91 deletions
|
@ -36,6 +36,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <KDecoration2/Decoration>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QStyleHints>
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <QElapsedTimer>
|
||||
|
||||
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;
|
||||
|
|
26
client.cpp
26
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()) {
|
||||
|
|
5
client.h
5
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<Decoration::DecoratedClientImpl> m_decoratedClient;
|
||||
QElapsedTimer m_decorationDoubleClickTimer;
|
||||
QStringList activityList;
|
||||
int m_activityUpdatesBlocked;
|
||||
bool m_blockedActivityUpdatesRequireTransients;
|
||||
|
|
65
events.cpp
65
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue