From deaff68a84ad3a96c4a6d03c3d095e1fc9209248 Mon Sep 17 00:00:00 2001 From: Reion Wong Date: Sat, 29 Aug 2026 20:38:43 -0400 Subject: [PATCH] Port plugins to current KWin --- CMakeLists.txt | 21 +- plugins/CMakeLists.txt | 59 ++-- plugins/decoration3/CMakeLists.txt | 45 ++++ plugins/decoration3/button.cpp | 91 +++++++ plugins/decoration3/button.h | 24 ++ plugins/decoration3/cutefishos.json | 19 ++ plugins/decoration3/decoration.cpp | 252 ++++++++++++++++++ plugins/decoration3/decoration.h | 65 +++++ .../cutefishlauncher/contents/code/main.js | 25 ++ scripts/cutefishlauncher/contents/main.js | 24 -- scripts/cutefishlauncher/metadata.desktop | 2 +- scripts/cutefishlauncher/metadata.json | 20 ++ 12 files changed, 590 insertions(+), 57 deletions(-) create mode 100644 plugins/decoration3/CMakeLists.txt create mode 100644 plugins/decoration3/button.cpp create mode 100644 plugins/decoration3/button.h create mode 100644 plugins/decoration3/cutefishos.json create mode 100644 plugins/decoration3/decoration.cpp create mode 100644 plugins/decoration3/decoration.h create mode 100644 scripts/cutefishlauncher/contents/code/main.js delete mode 100644 scripts/cutefishlauncher/contents/main.js create mode 100644 scripts/cutefishlauncher/metadata.json diff --git a/CMakeLists.txt b/CMakeLists.txt index e029074..e00b21c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,14 +9,19 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) +include(GNUInstallDirs) + +set(CUTEFISH_KWIN_CONFIG_DIR "/etc/xdg" CACHE PATH "Directory for system KWin configuration") +set(CUTEFISH_KWIN_DATA_DIR "${CMAKE_INSTALL_DATAROOTDIR}/kwin" CACHE PATH "Directory for KWin scripts and tabbox layouts") + add_subdirectory(plugins) -install(FILES config/kglobalshortcutsrc DESTINATION /etc/xdg) -install(FILES config/kwinrc DESTINATION /etc/xdg) -install(FILES config/kwinrulesrc DESTINATION /etc/xdg) +install(FILES config/kglobalshortcutsrc DESTINATION "${CUTEFISH_KWIN_CONFIG_DIR}") +install(FILES config/kwinrc DESTINATION "${CUTEFISH_KWIN_CONFIG_DIR}") +install(FILES config/kwinrulesrc DESTINATION "${CUTEFISH_KWIN_CONFIG_DIR}") -install(DIRECTORY scripts/cutefishlauncher DESTINATION /usr/share/kwin/scripts) -install(DIRECTORY scripts/cutefish_squash DESTINATION /usr/share/kwin/effects) -install(DIRECTORY scripts/cutefish_scale DESTINATION /usr/share/kwin/effects) -install(DIRECTORY scripts/cutefish_popups DESTINATION /usr/share/kwin/effects) -install(DIRECTORY tabbox/cutefish_thumbnail DESTINATION /usr/share/kwin/tabbox) +install(DIRECTORY scripts/cutefishlauncher DESTINATION "${CUTEFISH_KWIN_DATA_DIR}/scripts") +install(DIRECTORY scripts/cutefish_squash DESTINATION "${CUTEFISH_KWIN_DATA_DIR}/effects") +install(DIRECTORY scripts/cutefish_scale DESTINATION "${CUTEFISH_KWIN_DATA_DIR}/effects") +install(DIRECTORY scripts/cutefish_popups DESTINATION "${CUTEFISH_KWIN_DATA_DIR}/effects") +install(DIRECTORY tabbox/cutefish_thumbnail DESTINATION "${CUTEFISH_KWIN_DATA_DIR}/tabbox") diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 071d8a1..e379599 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,29 +1,40 @@ -find_package(Qt5 CONFIG REQUIRED COMPONENTS Core Gui) -find_package(KF5CoreAddons REQUIRED) -find_package(KF5WindowSystem REQUIRED) +option(CUTEFISH_BUILD_KWIN6_DECORATION "Build the KDecoration3 plugin used by KWin6" ON) +option(CUTEFISH_BUILD_KWIN5_DECORATION "Build the legacy KDecoration2 plugin" OFF) +option(CUTEFISH_BUILD_KWIN5_EFFECT "Build the legacy KWin5 C++ effect" OFF) -# 获取qmake -get_target_property(QT_QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE} IMPORTED_LOCATION) -if(NOT QT_QMAKE_EXECUTABLE) - message(FATAL_ERROR "qmake is not found.") +if(CUTEFISH_BUILD_KWIN6_DECORATION) + find_package(KDecoration3 QUIET) + if(KDecoration3_FOUND) + add_subdirectory(decoration3) + message(STATUS "KDecoration3 found: building Cutefish KWin6 decoration") + else() + message(WARNING "KDecoration3 was not found; the KWin6 decoration will not be built. Install libkdecorations3-dev or disable CUTEFISH_BUILD_KWIN6_DECORATION.") + endif() endif() -# execute the command "qmake -query QT_INSTALL_PLUGINS" to get the path of plugins dir. -execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS - OUTPUT_VARIABLE QT_PLUGINS_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE -) -if(QT_PLUGINS_DIR) - message(STATUS "Qt5 plugin directory:" "${QT_PLUGINS_DIR}") -else() - message(FATAL_ERROR "Qt5 plugin directory cannot be detected.") +if(CUTEFISH_BUILD_KWIN5_DECORATION) + find_package(Qt5 CONFIG QUIET COMPONENTS Core Gui Widgets X11Extras) + find_package(KF5CoreAddons QUIET) + find_package(KF5Config QUIET) + find_package(KF5WindowSystem QUIET) + find_package(KDecoration2 QUIET) + if(Qt5_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND AND KF5WindowSystem_FOUND AND KDecoration2_FOUND) + find_program(QT_QMAKE_EXECUTABLE qmake) + if(QT_QMAKE_EXECUTABLE) + execute_process(COMMAND "${QT_QMAKE_EXECUTABLE}" -query QT_INSTALL_PLUGINS + OUTPUT_VARIABLE QT_PLUGINS_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + if(QT_PLUGINS_DIR) + add_subdirectory(decoration) + else() + message(WARNING "Qt5 plugin directory could not be detected; skipping KDecoration2") + endif() + else() + message(WARNING "KDecoration2 dependencies were not found; skipping the legacy KWin5 decoration") + endif() endif() -# set(CMAKE_INCLUDE_CURRENT_DIR ON) -# set(CMAKE_AUTOMOC ON) -# set(CMAKE_AUTOUIC ON) -# set(CMAKE_AUTORCC ON) - -# add_subdirectory(blur) -add_subdirectory(decoration) -add_subdirectory(roundedwindow) \ No newline at end of file +if(CUTEFISH_BUILD_KWIN5_EFFECT) + message(WARNING "The roundedwindow C++ effect still uses private KWin5 APIs and is disabled by default on current KDE. The JavaScript effects are installed separately.") + add_subdirectory(roundedwindow) +endif() diff --git a/plugins/decoration3/CMakeLists.txt b/plugins/decoration3/CMakeLists.txt new file mode 100644 index 0000000..5fcce5b --- /dev/null +++ b/plugins/decoration3/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.16) +project(cutefishdecoration3 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +include(GNUInstallDirs) + +find_package(Qt6 CONFIG REQUIRED COMPONENTS Core Gui Widgets) +find_package(KF6CoreAddons REQUIRED) +find_package(KDecoration3 REQUIRED) + +set(decoration3_SRCS + decoration.cpp + button.cpp + "${CMAKE_CURRENT_SOURCE_DIR}/../decoration/resources.qrc" +) + +add_library(cutefishdecoration3 MODULE ${decoration3_SRCS}) + +target_link_libraries(cutefishdecoration3 + PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Widgets + KF6::CoreAddons + KDecoration3::KDecoration +) + +if(NOT KDE_INSTALL_PLUGINDIR) + find_program(QT6_QTPATHS_EXECUTABLE qtpaths6) + if(QT6_QTPATHS_EXECUTABLE) + execute_process(COMMAND "${QT6_QTPATHS_EXECUTABLE}" --query QT_INSTALL_PLUGINS + OUTPUT_VARIABLE KDE_INSTALL_PLUGINDIR OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() +endif() + +if(NOT KDE_INSTALL_PLUGINDIR) + set(KDE_INSTALL_PLUGINDIR "${CMAKE_INSTALL_LIBDIR}/qt6/plugins") +endif() + +install(TARGETS cutefishdecoration3 + DESTINATION "${KDE_INSTALL_PLUGINDIR}/org.kde.kdecoration3") diff --git a/plugins/decoration3/button.cpp b/plugins/decoration3/button.cpp new file mode 100644 index 0000000..b45bf9d --- /dev/null +++ b/plugins/decoration3/button.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 PandaOS Team. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "button.h" +#include "decoration.h" + +#include + +#include + +Button::Button(KDecoration3::DecorationButtonType type, + KDecoration3::Decoration *decoration, + QObject *parent) + : KDecoration3::DecorationButton(type, decoration, parent) +{ + auto *window = decoration ? decoration->window() : nullptr; + if (!window) { + setVisible(false); + return; + } + + switch (type) { + case KDecoration3::DecorationButtonType::Minimize: + setVisible(window->isMinimizeable()); + connect(window, &KDecoration3::DecoratedWindow::minimizeableChanged, this, &Button::setVisible); + break; + case KDecoration3::DecorationButtonType::Maximize: + setVisible(window->isMaximizeable()); + connect(window, &KDecoration3::DecoratedWindow::maximizeableChanged, this, &Button::setVisible); + break; + case KDecoration3::DecorationButtonType::Close: + setVisible(window->isCloseable()); + connect(window, &KDecoration3::DecoratedWindow::closeableChanged, this, &Button::setVisible); + break; + case KDecoration3::DecorationButtonType::Menu: + break; + default: + setVisible(false); + break; + } +} + +KDecoration3::DecorationButton *Button::create(KDecoration3::DecorationButtonType type, + KDecoration3::Decoration *decoration, + QObject *parent) +{ + return new Button(type, decoration, parent); +} + +void Button::paint(QPainter *painter, const QRectF &repaintArea) +{ + Q_UNUSED(repaintArea) + + auto *decoration = qobject_cast(this->decoration()); + if (!decoration) { + return; + } + + const QRectF buttonRect = geometry(); + const qreal scale = decoration->devicePixelRatio(); + const QRectF hoverRect = buttonRect.adjusted(2 * scale, 2 * scale, -2 * scale, -2 * scale); + const QRectF imageRect = QRectF(0, 0, 24 * scale, 24 * scale); + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + painter->setRenderHint(QPainter::SmoothPixmapTransform, false); + if (isHovered() || isPressed()) { + painter->setPen(Qt::NoPen); + painter->setBrush(decoration->darkMode() + ? (isPressed() ? QColor(255, 255, 255, 26) : QColor(255, 255, 255, 38)) + : (isPressed() ? QColor(0, 0, 0, 38) : QColor(0, 0, 0, 26))); + painter->drawRoundedRect(hoverRect, hoverRect.height() / 2, hoverRect.height() / 2); + } + + if (type() == KDecoration3::DecorationButtonType::Menu) { + if (auto *window = decoration->window()) { + window->icon().paint(painter, buttonRect.toRect()); + } + } else { + const QPixmap pixmap = decoration->buttonPixmap(type(), isChecked()); + QRectF centered = imageRect; + centered.moveCenter(buttonRect.center()); + if (!pixmap.isNull()) { + painter->drawPixmap(centered, pixmap, pixmap.rect()); + } + } + painter->restore(); +} diff --git a/plugins/decoration3/button.h b/plugins/decoration3/button.h new file mode 100644 index 0000000..8ff34b9 --- /dev/null +++ b/plugins/decoration3/button.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 PandaOS Team. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +class Button : public KDecoration3::DecorationButton +{ +public: + explicit Button(KDecoration3::DecorationButtonType type, + KDecoration3::Decoration *decoration, + QObject *parent = nullptr); + + static KDecoration3::DecorationButton *create(KDecoration3::DecorationButtonType type, + KDecoration3::Decoration *decoration, + QObject *parent); + +protected: + void paint(QPainter *painter, const QRectF &repaintArea) override; +}; diff --git a/plugins/decoration3/cutefishos.json b/plugins/decoration3/cutefishos.json new file mode 100644 index 0000000..a694784 --- /dev/null +++ b/plugins/decoration3/cutefishos.json @@ -0,0 +1,19 @@ +{ + "KPlugin": { + "Description": "CutefishOS window decoration for KDE Plasma 6", + "EnabledByDefault": true, + "Id": "org.cutefish.decoration", + "Name": "CutefishOS Window Frame", + "ServiceTypes": [ + "org.kde.kdecoration3" + ], + "Version": "1.0" + }, + "org.kde.kdecoration3": { + "blur": false, + "recommended": true, + "styles": [ + "titled" + ] + } +} diff --git a/plugins/decoration3/decoration.cpp b/plugins/decoration3/decoration.cpp new file mode 100644 index 0000000..dfd0377 --- /dev/null +++ b/plugins/decoration3/decoration.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2020 PandaOS Team. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "decoration.h" +#include "button.h" + +#include +#include +#include + +#include +#include + +K_PLUGIN_FACTORY_WITH_JSON(CutefishDecorationFactory, "cutefishos.json", + registerPlugin();) + +namespace Cutefish +{ + +Decoration::Decoration(QObject *parent, const QVariantList &args) + : KDecoration3::Decoration(parent, args) + , m_themeSettings(QSettings::UserScope, QStringLiteral("cutefishos"), QStringLiteral("theme")) +{ +} + +bool Decoration::init() +{ + if (!window()) { + return false; + } + + m_devicePixelRatio = m_themeSettings.value(QStringLiteral("PixelRatio"), 1.0).toReal(); + if (m_devicePixelRatio <= 0) { + m_devicePixelRatio = 1.0; + } + m_frameRadius = qRound(11 * m_devicePixelRatio); + + updateColors(); + updateButtonPixmaps(); + + m_leftButtons = new KDecoration3::DecorationButtonGroup( + KDecoration3::DecorationButtonGroup::Position::Left, this, &Button::create); + m_rightButtons = new KDecoration3::DecorationButtonGroup( + KDecoration3::DecorationButtonGroup::Position::Right, this, &Button::create); + + auto window = this->window(); + connect(window, &KDecoration3::DecoratedWindow::captionChanged, this, [this] { update(); }); + connect(window, &KDecoration3::DecoratedWindow::activeChanged, this, [this] { update(); }); + connect(window, &KDecoration3::DecoratedWindow::maximizedChanged, this, [this] { + updateGeometry(); + updateButtonsGeometry(); + update(); + }); + connect(window, &KDecoration3::DecoratedWindow::widthChanged, this, [this] { + updateGeometry(); + updateButtonsGeometry(); + }); + connect(window, &KDecoration3::DecoratedWindow::heightChanged, this, [this] { updateGeometry(); }); + + if (settings()) { + connect(settings().get(), &KDecoration3::DecorationSettings::fontChanged, this, [this] { + updateGeometry(); + update(); + }); + connect(settings().get(), &KDecoration3::DecorationSettings::spacingChanged, this, [this] { + updateButtonsGeometry(); + update(); + }); + connect(settings().get(), &KDecoration3::DecorationSettings::reconfigured, this, [this] { + updateGeometry(); + updateButtonsGeometry(); + update(); + }); + } + + updateGeometry(); + updateButtonsGeometry(); + return true; +} + +void Decoration::paint(QPainter *painter, const QRectF &repaintArea) +{ + Q_UNUSED(repaintArea) + + if (!window()) { + return; + } + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + painter->setPen(Qt::NoPen); + painter->setBrush(titleBarBackgroundColor()); + + if (!window()->isShaded() && !window()->isMaximized()) { + painter->drawRoundedRect(rect(), m_frameRadius, m_frameRadius); + } else { + painter->drawRect(rect()); + } + painter->restore(); + + if (m_leftButtons) { + m_leftButtons->paint(painter, repaintArea); + } + if (m_rightButtons) { + m_rightButtons->paint(painter, repaintArea); + } + paintCaption(painter); +} + +void Decoration::updateGeometry() +{ + if (!window()) { + return; + } + + const qreal height = titleBarHeight(); + setBorders(QMarginsF(0, height, 0, 0)); + setResizeOnlyBorders(QMarginsF(5, 5, 5, 5)); + setTitleBar(QRectF(0, 0, window()->width(), height)); +} + +void Decoration::updateButtonsGeometry() +{ + if (!window() || !m_leftButtons || !m_rightButtons) { + return; + } + + const QSizeF buttonSize(titleBarHeight(), titleBarHeight()); + const auto buttons = m_leftButtons->buttons() + m_rightButtons->buttons(); + for (auto *button : buttons) { + button->setGeometry(QRectF(QPointF(0, 0), buttonSize)); + } + + constexpr qreal spacing = 8.0; + m_leftButtons->setSpacing(spacing); + m_leftButtons->setPos(QPointF(0, 0)); + m_rightButtons->setSpacing(spacing); + m_rightButtons->setPos(QPointF(size().width() - m_rightButtons->geometry().width() - 2, 0)); +} + +void Decoration::updateColors() +{ + // The theme settings are intentionally read once per decoration. KWin creates a new + // decoration when the window/theme is reconfigured, avoiding a dependency on KDE5 APIs. +} + +void Decoration::updateButtonPixmaps() +{ + const auto load = [](const QString &path) { + return QPixmap(path); + }; + m_closeBtnPixmap = load(pixmapPath(KDecoration3::DecorationButtonType::Close, false)); + m_maximizeBtnPixmap = load(pixmapPath(KDecoration3::DecorationButtonType::Maximize, false)); + m_minimizeBtnPixmap = load(pixmapPath(KDecoration3::DecorationButtonType::Minimize, false)); + m_restoreBtnPixmap = load(pixmapPath(KDecoration3::DecorationButtonType::Maximize, true)); +} + +QPixmap Decoration::buttonPixmap(KDecoration3::DecorationButtonType type, bool checked) const +{ + switch (type) { + case KDecoration3::DecorationButtonType::Close: + return m_closeBtnPixmap; + case KDecoration3::DecorationButtonType::Maximize: + return checked ? m_restoreBtnPixmap : m_maximizeBtnPixmap; + case KDecoration3::DecorationButtonType::Minimize: + return m_minimizeBtnPixmap; + default: + return {}; + } +} + +QString Decoration::pixmapPath(KDecoration3::DecorationButtonType type, bool checked) const +{ + const QString mode = darkMode() ? QStringLiteral("dark") : QStringLiteral("light"); + QString name; + switch (type) { + case KDecoration3::DecorationButtonType::Close: + name = QStringLiteral("close_normal.svg"); + break; + case KDecoration3::DecorationButtonType::Maximize: + name = checked ? QStringLiteral("restore_normal.svg") : QStringLiteral("maximize_normal.svg"); + break; + case KDecoration3::DecorationButtonType::Minimize: + name = QStringLiteral("minimize_normal.svg"); + break; + default: + return {}; + } + return QStringLiteral(":/images/%1/%2").arg(mode, name); +} + +int Decoration::titleBarHeight() const +{ + return qMax(1, qRound(m_titleBarHeight * m_devicePixelRatio)); +} + +bool Decoration::darkMode() const +{ + return m_themeSettings.value(QStringLiteral("DarkMode"), false).toBool(); +} + +QColor Decoration::titleBarBackgroundColor() const +{ + return darkMode() ? m_titleBarBgDarkColor : m_titleBarBgColor; +} + +QColor Decoration::titleBarForegroundColor() const +{ + if (window() && window()->isActive()) { + return darkMode() ? m_titleBarFgDarkColor : m_titleBarFgColor; + } + return darkMode() ? m_unfocusedFgDarkColor : m_unfocusedFgColor; +} + +void Decoration::paintCaption(QPainter *painter) const +{ + if (!window()) { + return; + } + + QFont font = settings() ? settings()->font() : QFont(); + QFontMetricsF metrics(font); + const QRectF titleRect(0, 0, size().width(), titleBarHeight()); + const qreal left = m_leftButtons ? m_leftButtons->geometry().width() + 20 : 20; + const qreal right = m_rightButtons ? m_rightButtons->geometry().width() + 20 : 20; + const QRectF available = titleRect.adjusted(left, 0, -right, 0); + const qreal textWidth = metrics.horizontalAdvance(window()->caption()); + const QRectF natural((size().width() - textWidth) / 2, 0, textWidth, titleBarHeight()); + + Qt::Alignment alignment = Qt::AlignCenter; + QRectF captionRect = titleRect; + if (natural.left() < available.left()) { + captionRect = available; + alignment = Qt::AlignLeft | Qt::AlignVCenter; + } else if (natural.right() > available.right()) { + captionRect = available; + alignment = Qt::AlignRight | Qt::AlignVCenter; + } + + painter->save(); + painter->setFont(font); + painter->setPen(titleBarForegroundColor()); + painter->drawText(captionRect, alignment, metrics.elidedText(window()->caption(), Qt::ElideMiddle, qRound(captionRect.width()))); + painter->restore(); +} + +} + +#include "decoration.moc" diff --git a/plugins/decoration3/decoration.h b/plugins/decoration3/decoration.h new file mode 100644 index 0000000..ae61d4a --- /dev/null +++ b/plugins/decoration3/decoration.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 PandaOS Team. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include + +#include +#include + +namespace Cutefish +{ + +class Decoration : public KDecoration3::Decoration +{ + Q_OBJECT + +public: + explicit Decoration(QObject *parent = nullptr, const QVariantList &args = {}); + ~Decoration() override = default; + + bool init() override; + void paint(QPainter *painter, const QRectF &repaintArea) override; + + bool darkMode() const; + qreal devicePixelRatio() const { return m_devicePixelRatio; } + QPixmap buttonPixmap(KDecoration3::DecorationButtonType type, bool checked = false) const; + +private: + void updateGeometry(); + void updateButtonsGeometry(); + void updateColors(); + void updateButtonPixmaps(); + void paintCaption(QPainter *painter) const; + + int titleBarHeight() const; + QColor titleBarBackgroundColor() const; + QColor titleBarForegroundColor() const; + QString pixmapPath(KDecoration3::DecorationButtonType type, bool checked) const; + + KDecoration3::DecorationButtonGroup *m_leftButtons = nullptr; + KDecoration3::DecorationButtonGroup *m_rightButtons = nullptr; + + qreal m_devicePixelRatio = 1.0; + int m_titleBarHeight = 30; + int m_frameRadius = 11; + QColor m_titleBarBgColor = QColor(255, 255, 255); + QColor m_titleBarFgColor = QColor(56, 56, 56); + QColor m_unfocusedFgColor = QColor(127, 127, 127); + QColor m_titleBarBgDarkColor = QColor(44, 44, 45); + QColor m_titleBarFgDarkColor = QColor(202, 203, 206); + QColor m_unfocusedFgDarkColor = QColor(112, 112, 112); + + QSettings m_themeSettings; + QPixmap m_closeBtnPixmap; + QPixmap m_maximizeBtnPixmap; + QPixmap m_minimizeBtnPixmap; + QPixmap m_restoreBtnPixmap; +}; + +} diff --git a/scripts/cutefishlauncher/contents/code/main.js b/scripts/cutefishlauncher/contents/code/main.js new file mode 100644 index 0000000..8d09285 --- /dev/null +++ b/scripts/cutefishlauncher/contents/code/main.js @@ -0,0 +1,25 @@ +"use strict"; + +function forceFullScreen(window) { + var screenGeometry = workspace.clientArea(KWin.ScreenArea, window); + window.frameGeometry = screenGeometry; +} + +function setupConnection(window) { + if (window.resourceClass != "cutefish-launcher" + || window.resourceName != "cutefish-launcher" || window.dialog) { + return; + } + + forceFullScreen(window); + window.frameGeometryChanged.connect(function () { + forceFullScreen(window); + }); +} + +workspace.windowAdded.connect(setupConnection); + +var windows = workspace.windowList(); +for (var i = 0; i < windows.length; i++) { + setupConnection(windows[i]); +} diff --git a/scripts/cutefishlauncher/contents/main.js b/scripts/cutefishlauncher/contents/main.js deleted file mode 100644 index 46073d0..0000000 --- a/scripts/cutefishlauncher/contents/main.js +++ /dev/null @@ -1,24 +0,0 @@ -function forceFullScreen(client) { - var screen = client.screen; - var screenGeometry = workspace.clientArea(KWin.ScreenArea, screen, 0); - client.geometry = screenGeometry; -} - -function setupConnection(client) { - if (client.resourceClass != "cutefish-launcher" - || client.resourceName != "cutefish-launcher" || client.dialog) { - return; - } - - forceFullScreen(client) - client.geometryChanged.connect(client, function () { - forceFullScreen(this); - }); -} - -workspace.clientAdded.connect(setupConnection); -// connect all existing clients -var clients = workspace.clientList(); -for (var i = 0; i < clients.length; i++) { - setupConnection(clients[i]); -} \ No newline at end of file diff --git a/scripts/cutefishlauncher/metadata.desktop b/scripts/cutefishlauncher/metadata.desktop index 1f306d5..e2d326d 100644 --- a/scripts/cutefishlauncher/metadata.desktop +++ b/scripts/cutefishlauncher/metadata.desktop @@ -4,7 +4,7 @@ Comment=Force the cutefish-launcher window keep in screen area Icon=preferences-system-windows-script-test X-Plasma-API=javascript -X-Plasma-MainScript=main.js +X-Plasma-MainScript=code/main.js X-KDE-PluginInfo-Author=revenmartin X-KDE-PluginInfo-Email=revenmartin@gmail.com diff --git a/scripts/cutefishlauncher/metadata.json b/scripts/cutefishlauncher/metadata.json new file mode 100644 index 0000000..1b7b4e8 --- /dev/null +++ b/scripts/cutefishlauncher/metadata.json @@ -0,0 +1,20 @@ +{ + "KPlugin": { + "Name": "CutefishOS Launcher", + "Description": "Force the cutefish-launcher window to fill the screen area", + "Icon": "preferences-system-windows-script-test", + "Authors": [ + { + "Name": "revenmartin", + "Email": "revenmartin@gmail.com" + } + ], + "EnabledByDefault": true, + "Id": "cutefishlauncher", + "Version": "0.1", + "License": "GPL-3.0-or-later" + }, + "X-Plasma-API": "javascript", + "X-Plasma-MainScript": "code/main.js", + "KPackageStructure": "KWin/Script" +}