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();
|
||||
}
|
||||
|
||||
bool AbstractClient::dockWantsInput() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -416,6 +416,18 @@ public:
|
|||
virtual const WindowRules* rules() const = 0;
|
||||
virtual void takeFocus() = 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());
|
||||
virtual xcb_timestamp_t userTime() const;
|
||||
virtual void updateWindowRules(Rules::Types selection) = 0;
|
||||
|
|
|
@ -371,8 +371,13 @@ void Workspace::takeActivity(AbstractClient* c, ActivityFlags flags)
|
|||
}
|
||||
cancelDelayFocus();
|
||||
}
|
||||
if (!flags.testFlag(ActivityFocusForce) && (c->isDock() || c->isSplash()))
|
||||
flags &= ~ActivityFocus; // toplevel menus and dock windows don't take focus if not forced
|
||||
if (!flags.testFlag(ActivityFocusForce) && (c->isDock() || c->isSplash())) {
|
||||
// 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->wantsInput() && (flags & ActivityFocus)) {
|
||||
// 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 testPanelTypeHasStrut_data();
|
||||
void testPanelTypeHasStrut();
|
||||
void testPanelActivate_data();
|
||||
void testPanelActivate();
|
||||
|
||||
private:
|
||||
ConnectionThread *m_connection = nullptr;
|
||||
|
@ -368,5 +370,36 @@ void PlasmaSurfaceTest::testPanelWindowsCanCover()
|
|||
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)
|
||||
#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 userCanSetNoBorder() const override;
|
||||
bool wantsInput() const override;
|
||||
bool dockWantsInput() const override;
|
||||
using AbstractClient::resizeWithChecks;
|
||||
void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override;
|
||||
using AbstractClient::setGeometry;
|
||||
|
|
Loading…
Reference in a new issue