Support docks which take input
Summary: On X11 one needs to force activate a panel to pass it focus. This change implements something similar for Wayland but a little bit more stateful by using a request on the PlasmaShellSurface. If set KWin will activate the panel. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D3037
This commit is contained in:
parent
01667cacea
commit
03d706150a
6 changed files with 68 additions and 2 deletions
|
@ -1634,4 +1634,9 @@ QRect AbstractClient::inputGeometry() const
|
||||||
return Toplevel::inputGeometry();
|
return Toplevel::inputGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AbstractClient::dockWantsInput() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,6 +416,18 @@ public:
|
||||||
virtual const WindowRules* rules() const = 0;
|
virtual const WindowRules* rules() const = 0;
|
||||||
virtual void takeFocus() = 0;
|
virtual void takeFocus() = 0;
|
||||||
virtual bool wantsInput() const = 0;
|
virtual bool wantsInput() const = 0;
|
||||||
|
/**
|
||||||
|
* Whether a dock window wants input.
|
||||||
|
*
|
||||||
|
* By default KWin doesn't pass focus to a dock window unless a force activate
|
||||||
|
* request is provided.
|
||||||
|
*
|
||||||
|
* This method allows to have dock windows take focus also through flags set on
|
||||||
|
* the window.
|
||||||
|
*
|
||||||
|
* The default implementation returns @c false.
|
||||||
|
**/
|
||||||
|
virtual bool dockWantsInput() const;
|
||||||
void checkWorkspacePosition(QRect oldGeometry = QRect(), int oldDesktop = -2, QRect oldClientGeometry = QRect());
|
void checkWorkspacePosition(QRect oldGeometry = QRect(), int oldDesktop = -2, QRect oldClientGeometry = QRect());
|
||||||
virtual xcb_timestamp_t userTime() const;
|
virtual xcb_timestamp_t userTime() const;
|
||||||
virtual void updateWindowRules(Rules::Types selection) = 0;
|
virtual void updateWindowRules(Rules::Types selection) = 0;
|
||||||
|
|
|
@ -371,8 +371,13 @@ void Workspace::takeActivity(AbstractClient* c, ActivityFlags flags)
|
||||||
}
|
}
|
||||||
cancelDelayFocus();
|
cancelDelayFocus();
|
||||||
}
|
}
|
||||||
if (!flags.testFlag(ActivityFocusForce) && (c->isDock() || c->isSplash()))
|
if (!flags.testFlag(ActivityFocusForce) && (c->isDock() || c->isSplash())) {
|
||||||
flags &= ~ActivityFocus; // toplevel menus and dock windows don't take focus if not forced
|
// toplevel menus and dock windows don't take focus if not forced
|
||||||
|
// and don't have a flag that they take focus
|
||||||
|
if (!c->dockWantsInput()) {
|
||||||
|
flags &= ~ActivityFocus;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (c->isShade()) {
|
if (c->isShade()) {
|
||||||
if (c->wantsInput() && (flags & ActivityFocus)) {
|
if (c->wantsInput() && (flags & ActivityFocus)) {
|
||||||
// client cannot accept focus, but at least the window should be active (window menu, et. al. )
|
// client cannot accept focus, but at least the window should be active (window menu, et. al. )
|
||||||
|
|
|
@ -59,6 +59,8 @@ private Q_SLOTS:
|
||||||
void testOSDPlacement();
|
void testOSDPlacement();
|
||||||
void testPanelTypeHasStrut_data();
|
void testPanelTypeHasStrut_data();
|
||||||
void testPanelTypeHasStrut();
|
void testPanelTypeHasStrut();
|
||||||
|
void testPanelActivate_data();
|
||||||
|
void testPanelActivate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConnectionThread *m_connection = nullptr;
|
ConnectionThread *m_connection = nullptr;
|
||||||
|
@ -368,5 +370,36 @@ void PlasmaSurfaceTest::testPanelWindowsCanCover()
|
||||||
QCOMPARE(stackingOrder.last(), panel);
|
QCOMPARE(stackingOrder.last(), panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlasmaSurfaceTest::testPanelActivate_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<bool>("wantsFocus");
|
||||||
|
QTest::addColumn<bool>("active");
|
||||||
|
|
||||||
|
QTest::newRow("no focus") << false << false;
|
||||||
|
QTest::newRow("focus") << true << true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlasmaSurfaceTest::testPanelActivate()
|
||||||
|
{
|
||||||
|
QScopedPointer<Surface> surface(Test::createSurface());
|
||||||
|
QVERIFY(!surface.isNull());
|
||||||
|
QScopedPointer<QObject> shellSurface(Test::createShellSurface(Test::ShellSurfaceType::WlShell, surface.data()));
|
||||||
|
QVERIFY(!shellSurface.isNull());
|
||||||
|
QScopedPointer<PlasmaShellSurface> plasmaSurface(m_plasmaShell->createSurface(surface.data()));
|
||||||
|
QVERIFY(!plasmaSurface.isNull());
|
||||||
|
plasmaSurface->setRole(PlasmaShellSurface::Role::Panel);
|
||||||
|
QFETCH(bool, wantsFocus);
|
||||||
|
plasmaSurface->setPanelTakesFocus(wantsFocus);
|
||||||
|
|
||||||
|
auto panel = Test::renderAndWaitForShown(surface.data(), QSize(100, 200), Qt::blue);
|
||||||
|
|
||||||
|
QVERIFY(panel);
|
||||||
|
QCOMPARE(panel->windowType(), NET::Dock);
|
||||||
|
QVERIFY(panel->isDock());
|
||||||
|
QFETCH(bool, active);
|
||||||
|
QCOMPARE(panel->dockWantsInput(), active);
|
||||||
|
QCOMPARE(panel->isActive(), active);
|
||||||
|
}
|
||||||
|
|
||||||
WAYLANDTEST_MAIN(PlasmaSurfaceTest)
|
WAYLANDTEST_MAIN(PlasmaSurfaceTest)
|
||||||
#include "plasma_surface_test.moc"
|
#include "plasma_surface_test.moc"
|
||||||
|
|
|
@ -1373,4 +1373,14 @@ void ShellClient::showOnScreenEdge()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShellClient::dockWantsInput() const
|
||||||
|
{
|
||||||
|
if (m_plasmaShellSurface) {
|
||||||
|
if (m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Panel) {
|
||||||
|
return m_plasmaShellSurface->panelTakesFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ public:
|
||||||
bool userCanSetFullScreen() const override;
|
bool userCanSetFullScreen() const override;
|
||||||
bool userCanSetNoBorder() const override;
|
bool userCanSetNoBorder() const override;
|
||||||
bool wantsInput() const override;
|
bool wantsInput() const override;
|
||||||
|
bool dockWantsInput() const override;
|
||||||
using AbstractClient::resizeWithChecks;
|
using AbstractClient::resizeWithChecks;
|
||||||
void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override;
|
void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override;
|
||||||
using AbstractClient::setGeometry;
|
using AbstractClient::setGeometry;
|
||||||
|
|
Loading…
Reference in a new issue