From 254690e899dce589ce3b172c998b031a6405895b Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Tue, 1 Nov 2016 21:13:42 +0000 Subject: [PATCH 1/5] Correctly set i18n suffix in mousemark spinbox. Summary: QSpinBox can't handle plural suffixes. Something previously done by KIntSpinBox. Using setSuffix(ki18np("pixel", "pixels")).toString() does nothing, as at the time of conversion we don't know which one to use. This patch uses KPluralHandlingSpinBox and correct ki18np. Note, "new" dependency was already linked implicitly in other kwin, but we need to add it for this KCM. Test Plan: Opened KCM (in English) set counter to 1 pixel and 2 pixels. No longer had a big warning. Also appropriate number of s's appeared. Reviewers: #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D3222 --- CMakeLists.txt | 35 ++++++++--------- effects/mousemark/CMakeLists.txt | 1 + effects/mousemark/mousemark_config.cpp | 2 +- effects/mousemark/mousemark_config.ui | 53 ++++++++++++-------------- 4 files changed, 44 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f43cd81a8..52eeaea487 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Declarative KCMUtils KIO + TextWidgets NewStuff Service XmlGui @@ -340,10 +341,10 @@ add_subdirectory(helpers) ########### next target ############### set(kwin_KDEINIT_SRCS - workspace.cpp + workspace.cpp dbusinterface.cpp abstract_client.cpp - client.cpp + client.cpp client_machine.cpp cursor.cpp debug_console.cpp @@ -356,25 +357,25 @@ set(kwin_KDEINIT_SRCS pointer_input.cpp touch_input.cpp netinfo.cpp - placement.cpp - atoms.cpp - utils.cpp - layers.cpp - main.cpp - options.cpp + placement.cpp + atoms.cpp + utils.cpp + layers.cpp + main.cpp + options.cpp outline.cpp - events.cpp - killwindow.cpp - geometrytip.cpp + events.cpp + killwindow.cpp + geometrytip.cpp screens.cpp shadow.cpp - sm.cpp - group.cpp - manage.cpp + sm.cpp + group.cpp + manage.cpp overlaywindow.cpp - activation.cpp - useractions.cpp - geometry.cpp + activation.cpp + useractions.cpp + geometry.cpp rules.cpp composite.cpp toplevel.cpp diff --git a/effects/mousemark/CMakeLists.txt b/effects/mousemark/CMakeLists.txt index 5d95a8acd6..9002f7c344 100644 --- a/effects/mousemark/CMakeLists.txt +++ b/effects/mousemark/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(kwin_mousemark_config KF5::GlobalAccel KF5::I18n KF5::Service + KF5::TextWidgets KF5::XmlGui ) diff --git a/effects/mousemark/mousemark_config.cpp b/effects/mousemark/mousemark_config.cpp index 8f9f0d1927..68164a071b 100644 --- a/effects/mousemark/mousemark_config.cpp +++ b/effects/mousemark/mousemark_config.cpp @@ -52,7 +52,7 @@ MouseMarkEffectConfig::MouseMarkEffectConfig(QWidget* parent, const QVariantList { m_ui = new MouseMarkEffectConfigForm(this); - m_ui->kcfg_LineWidth->setSuffix(ki18np(" pixel", " pixels").toString()); + m_ui->kcfg_LineWidth->setSuffix(ki18np(" pixel", " pixels")); QVBoxLayout* layout = new QVBoxLayout(this); diff --git a/effects/mousemark/mousemark_config.ui b/effects/mousemark/mousemark_config.ui index b86db7e4cd..6bfbb3dfad 100644 --- a/effects/mousemark/mousemark_config.ui +++ b/effects/mousemark/mousemark_config.ui @@ -17,10 +17,10 @@ Appearance - + - &Width: + Wid&th: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -30,26 +30,7 @@ - - - - - 0 - 0 - - - - 1 - - - 10 - - - 3 - - - - + &Color: @@ -62,7 +43,7 @@ - + @@ -72,15 +53,24 @@ + + + + 1 + + + 10 + + + 3 + + + - - - KShortcutsEditor::GlobalAction - - + @@ -106,9 +96,14 @@ KShortcutsEditor QWidget -
KShortcutsEditor
+
kshortcutseditor.h
1
+ + KPluralHandlingSpinBox + QSpinBox +
kpluralhandlingspinbox.h
+
From 4730be084c1b071db5b0869f13e6c444a35e2fb3 Mon Sep 17 00:00:00 2001 From: James Pike Date: Wed, 2 Nov 2016 21:56:56 +0000 Subject: [PATCH 2/5] Support for workspace.clientList() in declarative script Summary: The version provided is only compatible with QtScript so it became necessary to split WorkspaceWrapper into a base class and two child classes, one for QtScript and one for QmlScript. BUG: 340125 FIXED-IN: 5.8.4 REVIEW: D3185 --- scripting/scriptedeffect.cpp | 2 +- scripting/scripting.cpp | 13 ++++++++++--- scripting/scripting.h | 23 +++++++++++++++++++---- scripting/workspace_wrapper.cpp | 30 ++++++++++++++++++++++++++---- scripting/workspace_wrapper.h | 33 +++++++++++++++++++++++++++++---- 5 files changed, 85 insertions(+), 16 deletions(-) diff --git a/scripting/scriptedeffect.cpp b/scripting/scriptedeffect.cpp index 0aa9a8b968..193ed958dc 100644 --- a/scripting/scriptedeffect.cpp +++ b/scripting/scriptedeffect.cpp @@ -492,7 +492,7 @@ bool ScriptedEffect::init(const QString &effectName, const QString &pathToScript m_engine->globalObject().setProperty(QStringLiteral("effects"), effectsObject, QScriptValue::Undeletable); m_engine->globalObject().setProperty(QStringLiteral("Effect"), m_engine->newQMetaObject(&ScriptedEffect::staticMetaObject)); #ifndef KWIN_UNIT_TEST - m_engine->globalObject().setProperty(QStringLiteral("KWin"), m_engine->newQMetaObject(&WorkspaceWrapper::staticMetaObject)); + m_engine->globalObject().setProperty(QStringLiteral("KWin"), m_engine->newQMetaObject(&QtScriptWorkspaceWrapper::staticMetaObject)); #endif m_engine->globalObject().setProperty(QStringLiteral("QEasingCurve"), m_engine->newQMetaObject(&QEasingCurve::staticMetaObject)); m_engine->globalObject().setProperty(QStringLiteral("effect"), m_engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater), QScriptValue::Undeletable); diff --git a/scripting/scripting.cpp b/scripting/scripting.cpp index 3e3ab5691e..a1817868be 100644 --- a/scripting/scripting.cpp +++ b/scripting/scripting.cpp @@ -46,6 +46,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -293,7 +294,7 @@ void KWin::Script::installScriptFunctions(QScriptEngine* engine) QScriptValue assertNotNullFunc = engine->newFunction(kwinAssertNotNull); engine->globalObject().setProperty(QStringLiteral("assertNotNull"), assertNotNullFunc); // global properties - engine->globalObject().setProperty(QStringLiteral("KWin"), engine->newQMetaObject(&WorkspaceWrapper::staticMetaObject)); + engine->globalObject().setProperty(QStringLiteral("KWin"), engine->newQMetaObject(&QtScriptWorkspaceWrapper::staticMetaObject)); QScriptValue workspace = engine->newQObject(Scripting::self()->workspaceWrapper(), QScriptEngine::QtOwnership, QScriptEngine::ExcludeSuperClassContents | QScriptEngine::ExcludeDeleteLater); engine->globalObject().setProperty(QStringLiteral("workspace"), workspace, QScriptValue::Undeletable); @@ -527,7 +528,7 @@ void KWin::ScriptUnloaderAgent::scriptUnload(qint64 id) KWin::DeclarativeScript::DeclarativeScript(int id, QString scriptName, QString pluginName, QObject* parent) : AbstractScript(id, scriptName, pluginName, parent) - , m_context(new QQmlContext(Scripting::self()->qmlEngine(), this)) + , m_context(new QQmlContext(Scripting::self()->declarativeScriptSharedContext(), this)) , m_component(new QQmlComponent(Scripting::self()->qmlEngine(), this)) { m_context->setContextProperty(QStringLiteral("KWin"), new JSEngineGlobalMethodsWrapper(this)); @@ -622,7 +623,8 @@ KWin::Scripting::Scripting(QObject *parent) : QObject(parent) , m_scriptsLock(new QMutex(QMutex::Recursive)) , m_qmlEngine(new QQmlEngine(this)) - , m_workspaceWrapper(new WorkspaceWrapper(this)) + , m_declarativeScriptSharedContext(new QQmlContext(m_qmlEngine, this)) + , m_workspaceWrapper(new QtScriptWorkspaceWrapper(this)) { init(); QDBusConnection::sessionBus().registerObject(QStringLiteral("/Scripting"), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportScriptableInvokables); @@ -647,6 +649,11 @@ void KWin::Scripting::init() m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("workspace"), m_workspaceWrapper); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("options"), options); + + m_declarativeScriptSharedContext->setContextProperty(QStringLiteral("workspace"), new DeclarativeScriptWorkspaceWrapper(this)); + // QQmlListProperty interfaces only work via properties, rebind them as functions here + QQmlExpression expr(m_declarativeScriptSharedContext, nullptr, "workspace.clientList = function() { return workspace.clients }"); + expr.evaluate(); } void KWin::Scripting::start() diff --git a/scripting/scripting.h b/scripting/scripting.h index d2682e22e0..02627e90ad 100644 --- a/scripting/scripting.h +++ b/scripting/scripting.h @@ -51,7 +51,7 @@ namespace KWin class AbstractClient; class Client; class ScriptUnloaderAgent; -class WorkspaceWrapper; +class QtScriptWorkspaceWrapper; class KWIN_EXPORT AbstractScript : public QObject { @@ -362,7 +362,9 @@ public: QQmlEngine *qmlEngine() const; QQmlEngine *qmlEngine(); - WorkspaceWrapper *workspaceWrapper() const; + QQmlContext *declarativeScriptSharedContext() const; + QQmlContext *declarativeScriptSharedContext(); + QtScriptWorkspaceWrapper *workspaceWrapper() const; AbstractScript *findScript(const QString &pluginName) const; @@ -381,7 +383,8 @@ private: LoadScriptList queryScriptsToLoad(); static Scripting *s_self; QQmlEngine *m_qmlEngine; - WorkspaceWrapper *m_workspaceWrapper; + QQmlContext *m_declarativeScriptSharedContext; + QtScriptWorkspaceWrapper *m_workspaceWrapper; }; inline @@ -397,7 +400,19 @@ QQmlEngine *Scripting::qmlEngine() } inline -WorkspaceWrapper *Scripting::workspaceWrapper() const +QQmlContext *Scripting::declarativeScriptSharedContext() const +{ + return m_declarativeScriptSharedContext; +} + +inline +QQmlContext *Scripting::declarativeScriptSharedContext() +{ + return m_declarativeScriptSharedContext; +} + +inline +QtScriptWorkspaceWrapper *Scripting::workspaceWrapper() const { return m_workspaceWrapper; } diff --git a/scripting/workspace_wrapper.cpp b/scripting/workspace_wrapper.cpp index 05aecb6eb6..d10054d576 100644 --- a/scripting/workspace_wrapper.cpp +++ b/scripting/workspace_wrapper.cpp @@ -90,12 +90,12 @@ void WorkspaceWrapper::setNumberOfDesktops(int count) VirtualDesktopManager::self()->setCount(count); } -#define GETTER( rettype, getterName ) \ -rettype WorkspaceWrapper::getterName( ) const { \ +#define GETTER( klass, rettype, getterName ) \ +rettype klass::getterName( ) const { \ return Workspace::self()->getterName(); \ } -GETTER(KWin::AbstractClient*, activeClient) -GETTER(QList< KWin::Client* >, clientList) +GETTER(WorkspaceWrapper, KWin::AbstractClient*, activeClient) +GETTER(QtScriptWorkspaceWrapper, QList< KWin::Client* >, clientList) #undef GETTER @@ -324,4 +324,26 @@ QSize WorkspaceWrapper::virtualScreenSize() const return screens()->size(); } +QtScriptWorkspaceWrapper::QtScriptWorkspaceWrapper(QObject* parent) + : WorkspaceWrapper(parent) {} + + +QQmlListProperty DeclarativeScriptWorkspaceWrapper::clients() +{ + return QQmlListProperty(this, 0, &DeclarativeScriptWorkspaceWrapper::countClientList, &DeclarativeScriptWorkspaceWrapper::atClientList); +} + +int DeclarativeScriptWorkspaceWrapper::countClientList(QQmlListProperty *clients) +{ + return Workspace::self()->clientList().size(); +} + +KWin::Client *DeclarativeScriptWorkspaceWrapper::atClientList(QQmlListProperty *clients, int index) +{ + return Workspace::self()->clientList().at(index); +} + +DeclarativeScriptWorkspaceWrapper::DeclarativeScriptWorkspaceWrapper(QObject* parent) + : WorkspaceWrapper(parent) {} + } // KWin diff --git a/scripting/workspace_wrapper.h b/scripting/workspace_wrapper.h index 5a6c2cbf71..d21989a788 100644 --- a/scripting/workspace_wrapper.h +++ b/scripting/workspace_wrapper.h @@ -26,6 +26,7 @@ along with this program. If not, see . #include #include #include +#include #include namespace KWin @@ -198,7 +199,10 @@ public: ElectricNone }; +protected: explicit WorkspaceWrapper(QObject* parent = nullptr); + +public: #define GETTERSETTERDEF( rettype, getter, setter ) \ rettype getter() const; \ void setter( rettype val ); @@ -222,10 +226,6 @@ void setter( rettype val ); QSize virtualScreenSize() const; QRect virtualScreenGeometry() const; - /** - * List of Clients currently managed by KWin. - **/ - Q_INVOKABLE QList< KWin::Client* > clientList() const; /** * Returns the geometry a Client can use with the specified option. * This method should be preferred over other methods providing screen sizes as the @@ -349,6 +349,31 @@ private Q_SLOTS: void setupClientConnections(KWin::Client* client); }; +class QtScriptWorkspaceWrapper : public WorkspaceWrapper +{ + Q_OBJECT +public: + /** + * List of Clients currently managed by KWin. + **/ + Q_INVOKABLE QList< KWin::Client* > clientList() const; + + explicit QtScriptWorkspaceWrapper(QObject* parent = nullptr); +}; + +class DeclarativeScriptWorkspaceWrapper : public WorkspaceWrapper +{ + Q_OBJECT + + Q_PROPERTY(QQmlListProperty clients READ clients) +public: + QQmlListProperty clients(); + static int countClientList(QQmlListProperty *clients); + static KWin::Client *atClientList(QQmlListProperty *clients, int index); + + explicit DeclarativeScriptWorkspaceWrapper(QObject* parent = nullptr); +}; + } #endif From be9ee989b19e51a61e257e7224786369ba87cbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 3 Nov 2016 08:13:25 +0100 Subject: [PATCH 3/5] [scripting] Fix export of WorkspaceWrapper in QtScript The export of the WorkspaceWrapper was changed to be a subclass with all the elements still being in the parent class. But the "workspace" was exported with QScriptEngine::ExcludeSuperClassContents. Thus all usages of workspace were broken and our tests started to fail on build.kde.org. This change removes the ExcludeSuperClassContents which means that also the QObject properties and slots are now exposed which was previously not the case. CCMAIL: github@chilon.net --- scripting/scripting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/scripting.cpp b/scripting/scripting.cpp index a1817868be..c25db76f5c 100644 --- a/scripting/scripting.cpp +++ b/scripting/scripting.cpp @@ -296,7 +296,7 @@ void KWin::Script::installScriptFunctions(QScriptEngine* engine) // global properties engine->globalObject().setProperty(QStringLiteral("KWin"), engine->newQMetaObject(&QtScriptWorkspaceWrapper::staticMetaObject)); QScriptValue workspace = engine->newQObject(Scripting::self()->workspaceWrapper(), QScriptEngine::QtOwnership, - QScriptEngine::ExcludeSuperClassContents | QScriptEngine::ExcludeDeleteLater); + QScriptEngine::ExcludeDeleteLater); engine->globalObject().setProperty(QStringLiteral("workspace"), workspace, QScriptValue::Undeletable); // install meta functions KWin::MetaScripting::registration(engine); From 6c121436e2c38624e89b2d607f573491a1a24b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 3 Nov 2016 08:17:11 +0100 Subject: [PATCH 4/5] [scripting] Silence unused variable warnings CCMAIL: github@chilon.net --- scripting/workspace_wrapper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripting/workspace_wrapper.cpp b/scripting/workspace_wrapper.cpp index d10054d576..461e0546c4 100644 --- a/scripting/workspace_wrapper.cpp +++ b/scripting/workspace_wrapper.cpp @@ -335,11 +335,13 @@ QQmlListProperty DeclarativeScriptWorkspaceWrapper::clients() int DeclarativeScriptWorkspaceWrapper::countClientList(QQmlListProperty *clients) { + Q_UNUSED(clients) return Workspace::self()->clientList().size(); } KWin::Client *DeclarativeScriptWorkspaceWrapper::atClientList(QQmlListProperty *clients, int index) { + Q_UNUSED(clients) return Workspace::self()->clientList().at(index); } From 679e41780888b428a64389e06d7e2738904f3a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 2 Nov 2016 12:35:47 +0100 Subject: [PATCH 5/5] Don't snap to auto-hidden panels Summary: When moving windows we don't want to snap against not visible windows like auto-hidden panels. BUG: 365892 FIXED-IN: 5.8.4 Test Plan: So far only auto-test, manual test will follow. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D3225 --- autotests/integration/move_resize_window_test.cpp | 1 - geometry.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/autotests/integration/move_resize_window_test.cpp b/autotests/integration/move_resize_window_test.cpp index 7bedad9948..77211faee2 100644 --- a/autotests/integration/move_resize_window_test.cpp +++ b/autotests/integration/move_resize_window_test.cpp @@ -664,7 +664,6 @@ void MoveResizeWindowTest::testAdjustClientGeometryOfAutohidingX11Panel() QVERIFY(panelHiddenSpy.wait()); // now try to snap again - QEXPECT_FAIL("", "BUG 365892", Continue); QCOMPARE(Workspace::self()->adjustClientPosition(testWindow, targetPoint, false), targetPoint); // and destroy the panel again diff --git a/geometry.cpp b/geometry.cpp index 73507b296f..812db7c143 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -527,6 +527,8 @@ QPoint Workspace::adjustClientPosition(AbstractClient* c, QPoint pos, bool unres continue; if ((*l)->isMinimized()) continue; // is minimized + if (!(*l)->isShown(false)) + continue; if ((*l)->tabGroup() && (*l) != (*l)->tabGroup()->current()) continue; // is not active tab if (!((*l)->isOnDesktop(c->desktop()) || c->isOnDesktop((*l)->desktop())))