Do not limit mouse actions to titleBarArea but allow on complete titleBarPosition
Summary: Mouse actions like wheel and double click were restricted to the titleBar area. This made the top most pixel non-interactive as it's not part of the titleBarArea. This change makes the complete titlebarPosition interactive. That is it includes for a "normal" (top) setup also the TopLeft/Top/Right section. Thus the top most pixel can be double clicked, mouse wheeled, etc. For the Wayland case the test case is adjusted. BUG: 362860 FIXED-IN: 5.7.0 Reviewers: #plasma Subscribers: plasma-devel Projects: #plasma Differential Revision: https://phabricator.kde.org/D1596
This commit is contained in:
parent
8d7d51e4ef
commit
14d12c0585
5 changed files with 85 additions and 5 deletions
|
@ -460,6 +460,31 @@ AbstractClient::Position AbstractClient::titlebarPosition() const
|
|||
return PositionTop;
|
||||
}
|
||||
|
||||
bool AbstractClient::titlebarPositionUnderMouse() const
|
||||
{
|
||||
if (!isDecorated()) {
|
||||
return false;
|
||||
}
|
||||
const auto sectionUnderMouse = decoration()->sectionUnderMouse();
|
||||
if (sectionUnderMouse == Qt::TitleBarArea) {
|
||||
return true;
|
||||
}
|
||||
// check other sections based on titlebarPosition
|
||||
switch (titlebarPosition()) {
|
||||
case AbstractClient::PositionTop:
|
||||
return (sectionUnderMouse == Qt::TopLeftSection || sectionUnderMouse == Qt::TopSection || sectionUnderMouse == Qt::TopRightSection);
|
||||
case AbstractClient::PositionLeft:
|
||||
return (sectionUnderMouse == Qt::TopLeftSection || sectionUnderMouse == Qt::LeftSection || sectionUnderMouse == Qt::BottomLeftSection);
|
||||
case AbstractClient::PositionRight:
|
||||
return (sectionUnderMouse == Qt::BottomRightSection || sectionUnderMouse == Qt::RightSection || sectionUnderMouse == Qt::TopRightSection);
|
||||
case AbstractClient::PositionBottom:
|
||||
return (sectionUnderMouse == Qt::BottomLeftSection || sectionUnderMouse == Qt::BottomSection || sectionUnderMouse == Qt::BottomRightSection);
|
||||
default:
|
||||
// nothing
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractClient::setMinimized(bool set)
|
||||
{
|
||||
set ? minimize() : unminimize();
|
||||
|
@ -1426,7 +1451,7 @@ bool AbstractClient::processDecorationButtonPress(QMouseEvent *event, bool ignor
|
|||
active = true;
|
||||
|
||||
// check whether it is a double click
|
||||
if (event->button() == Qt::LeftButton && decoration()->titleBar().contains(event->x(), event->y())) {
|
||||
if (event->button() == Qt::LeftButton && titlebarPositionUnderMouse()) {
|
||||
if (m_decoration.doubleClickTimer.isValid()) {
|
||||
const quint64 interval = m_decoration.doubleClickTimer.elapsed();
|
||||
m_decoration.doubleClickTimer.invalidate();
|
||||
|
@ -1479,7 +1504,7 @@ bool AbstractClient::processDecorationButtonPress(QMouseEvent *event, bool ignor
|
|||
void AbstractClient::processDecorationButtonRelease(QMouseEvent *event)
|
||||
{
|
||||
if (isDecorated()) {
|
||||
if (event->isAccepted() || !decoration()->titleBar().contains(event->pos())) {
|
||||
if (event->isAccepted() || !titlebarPositionUnderMouse()) {
|
||||
invalidateDecorationDoubleClickTimer(); // click was for the deco and shall not init a doubleclick
|
||||
}
|
||||
}
|
||||
|
|
|
@ -425,6 +425,7 @@ public:
|
|||
PositionBottomRight = PositionRight | PositionBottom
|
||||
};
|
||||
Position titlebarPosition() const;
|
||||
bool titlebarPositionUnderMouse() const;
|
||||
|
||||
// a helper for the workspace window packing. tests for screen validity and updates since in maximization case as with normal moving
|
||||
void packTo(int left, int top);
|
||||
|
|
|
@ -21,12 +21,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "platform.h"
|
||||
#include "abstract_client.h"
|
||||
#include "cursor.h"
|
||||
#include "pointer_input.h"
|
||||
#include "screenedge.h"
|
||||
#include "screens.h"
|
||||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
#include "shell_client.h"
|
||||
#include <kwineffects.h>
|
||||
#include "decorations/decoratedclient.h"
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/compositor.h>
|
||||
|
@ -43,6 +45,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <linux/input.h>
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::WindowFrameSection)
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -55,7 +59,9 @@ private Q_SLOTS:
|
|||
void initTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
void testAxis_data();
|
||||
void testAxis();
|
||||
void testDoubleClick_data();
|
||||
void testDoubleClick();
|
||||
void testHover();
|
||||
void testPressToMove_data();
|
||||
|
@ -239,6 +245,16 @@ void DecorationInputTest::cleanup()
|
|||
}
|
||||
}
|
||||
|
||||
void DecorationInputTest::testAxis_data()
|
||||
{
|
||||
QTest::addColumn<QPoint>("decoPoint");
|
||||
QTest::addColumn<Qt::WindowFrameSection>("expectedSection");
|
||||
|
||||
QTest::newRow("topLeft") << QPoint(0, 0) << Qt::TopLeftSection;
|
||||
QTest::newRow("top") << QPoint(250, 0) << Qt::TopSection;
|
||||
QTest::newRow("topRight") << QPoint(499, 0) << Qt::TopRightSection;
|
||||
}
|
||||
|
||||
void DecorationInputTest::testAxis()
|
||||
{
|
||||
AbstractClient *c = showWindow();
|
||||
|
@ -251,6 +267,8 @@ void DecorationInputTest::testAxis()
|
|||
|
||||
quint32 timestamp = 1;
|
||||
MOTION(QPoint(c->geometry().center().x(), c->clientPos().y() / 2));
|
||||
QVERIFY(!input()->pointer()->decoration().isNull());
|
||||
QCOMPARE(input()->pointer()->decoration()->decoration()->sectionUnderMouse(), Qt::TitleBarArea);
|
||||
|
||||
// TODO: mouse wheel direction looks wrong to me
|
||||
// simulate wheel
|
||||
|
@ -263,6 +281,27 @@ void DecorationInputTest::testAxis()
|
|||
kwinApp()->platform()->pointerAxisVertical(-5.0, timestamp++);
|
||||
QVERIFY(!c->keepBelow());
|
||||
QVERIFY(c->keepAbove());
|
||||
|
||||
// test top most deco pixel, BUG: 362860
|
||||
c->move(0, 0);
|
||||
QFETCH(QPoint, decoPoint);
|
||||
MOTION(decoPoint);
|
||||
QVERIFY(!input()->pointer()->decoration().isNull());
|
||||
QCOMPARE(input()->pointer()->decoration()->client(), c);
|
||||
QTEST(input()->pointer()->decoration()->decoration()->sectionUnderMouse(), "expectedSection");
|
||||
kwinApp()->platform()->pointerAxisVertical(5.0, timestamp++);
|
||||
QVERIFY(!c->keepBelow());
|
||||
QVERIFY(!c->keepAbove());
|
||||
}
|
||||
|
||||
void DecorationInputTest::testDoubleClick_data()
|
||||
{
|
||||
QTest::addColumn<QPoint>("decoPoint");
|
||||
QTest::addColumn<Qt::WindowFrameSection>("expectedSection");
|
||||
|
||||
QTest::newRow("topLeft") << QPoint(0, 0) << Qt::TopLeftSection;
|
||||
QTest::newRow("top") << QPoint(250, 0) << Qt::TopSection;
|
||||
QTest::newRow("topRight") << QPoint(499, 0) << Qt::TopRightSection;
|
||||
}
|
||||
|
||||
void KWin::DecorationInputTest::testDoubleClick()
|
||||
|
@ -288,6 +327,21 @@ void KWin::DecorationInputTest::testDoubleClick()
|
|||
PRESS;
|
||||
RELEASE;
|
||||
QVERIFY(!c->isOnAllDesktops());
|
||||
|
||||
// test top most deco pixel, BUG: 362860
|
||||
c->move(0, 0);
|
||||
QFETCH(QPoint, decoPoint);
|
||||
MOTION(decoPoint);
|
||||
QVERIFY(!input()->pointer()->decoration().isNull());
|
||||
QCOMPARE(input()->pointer()->decoration()->client(), c);
|
||||
QTEST(input()->pointer()->decoration()->decoration()->sectionUnderMouse(), "expectedSection");
|
||||
// double click
|
||||
PRESS;
|
||||
RELEASE;
|
||||
QVERIFY(!c->isOnAllDesktops());
|
||||
PRESS;
|
||||
RELEASE;
|
||||
QVERIFY(c->isOnAllDesktops());
|
||||
}
|
||||
|
||||
void DecorationInputTest::testHover()
|
||||
|
|
|
@ -1172,7 +1172,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() && !hor) {
|
||||
if (decoration()->titleBar().contains(x, y)) {
|
||||
if (titlebarPositionUnderMouse()) {
|
||||
performMouseCommand(options->operationTitlebarMouseWheel(delta), QPoint(x_root, y_root));
|
||||
}
|
||||
}
|
||||
|
@ -1204,7 +1204,7 @@ bool Client::buttonReleaseEvent(xcb_window_t w, int button, int state, int x, in
|
|||
x11ToQtKeyboardModifiers(state));
|
||||
event.setAccepted(false);
|
||||
QCoreApplication::sendEvent(decoration(), &event);
|
||||
if (event.isAccepted() || !decoration()->titleBar().contains(x, y)) {
|
||||
if (event.isAccepted() || !titlebarPositionUnderMouse()) {
|
||||
invalidateDecorationDoubleClickTimer(); // click was for the deco and shall not init a doubleclick
|
||||
}
|
||||
}
|
||||
|
|
|
@ -485,7 +485,7 @@ public:
|
|||
if (e.isAccepted()) {
|
||||
return true;
|
||||
}
|
||||
if (orientation == Qt::Vertical && decoration->decoration()->titleBar().contains(localPos.toPoint())) {
|
||||
if ((orientation == Qt::Vertical) && decoration->client()->titlebarPositionUnderMouse()) {
|
||||
decoration->client()->performMouseCommand(options->operationTitlebarMouseWheel(delta * -1),
|
||||
event->globalPosF().toPoint());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue