Advance Wayland and KDE package bring-up

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-14 10:51:06 +01:00
parent 51f3c21121
commit cf12defd28
15214 changed files with 20594243 additions and 269 deletions
@@ -0,0 +1,45 @@
# KI18N Translation Domain for this library
add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwintabbox\")
set(kcm_kwintabbox_PART_SRCS
${KWin_SOURCE_DIR}/src/tabbox/tabboxconfig.cpp
layoutpreview.cpp
main.cpp
thumbnailitem.cpp
kwintabboxconfigform.cpp
kwintabboxdata.cpp
shortcutsettings.cpp
)
ki18n_wrap_ui(kcm_kwintabbox_PART_SRCS main.ui)
qt_add_dbus_interface(kcm_kwintabbox_PART_SRCS ${KWin_SOURCE_DIR}/src/org.kde.kwin.Effects.xml kwin_effects_interface)
kconfig_add_kcfg_files(kcm_kwintabbox_PART_SRCS kwintabboxsettings.kcfgc kwinswitcheffectsettings.kcfgc)
kcoreaddons_add_plugin(kcm_kwintabbox SOURCES ${kcm_kwintabbox_PART_SRCS} INSTALL_NAMESPACE "plasma/kcms/systemsettings_qwidgets")
kcmutils_generate_desktop_file(kcm_kwintabbox)
target_link_libraries(kcm_kwintabbox
Qt::Quick
KF6::GlobalAccel
KF6::I18n
KF6::KCMUtils
KF6::NewStuffWidgets
KF6::Package
KF6::Service
KF6::XmlGui # For kkeysequencewidget
KF6::WidgetsAddons
)
if (KWIN_BUILD_X11)
target_link_libraries(kcm_kwintabbox
XCB::XCB
)
endif()
########### install files ###############
install(FILES thumbnails/falkon.png
thumbnails/kmail.png
thumbnails/systemsettings.png
thumbnails/dolphin.png
thumbnails/desktop.png
DESTINATION ${KDE_INSTALL_DATADIR}/kwin/kcm_kwintabbox)
install(FILES kwinswitcher.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR})
@@ -0,0 +1,4 @@
#! /usr/bin/env bash
$EXTRACTRC *.ui >> rc.cpp || exit 11
$XGETTEXT *.cpp -o $podir/kcm_kwintabbox.pot
rm -f rc.cpp
@@ -0,0 +1,138 @@
{
"KPlugin": {
"BugReportUrl": "https://bugs.kde.org/enter_bug.cgi?product=systemsettings&component=kcm_kwintabbox",
"Description": "Navigation Through Windows",
"Description[ar]": "التنقل بين النوافذ",
"Description[az]": "Pəncərələr arası naviqasiya",
"Description[be]": "Навігацыя па вокнах",
"Description[bg]": "Навигация през прозорците",
"Description[ca@valencia]": "Navegueu per les finestres",
"Description[ca]": "Navegació per les finestres",
"Description[cs]": "Navigace skrz okna",
"Description[da]": "Navigering gennem vinduer",
"Description[de]": "Zwischen Fenstern wechseln",
"Description[en_GB]": "Navigation Through Windows",
"Description[eo]": "Navigado Tra Fenestroj",
"Description[es]": "Navegación a través de las ventanas",
"Description[et]": "Akende vahel liikumine",
"Description[eu]": "Leihoen artean nabigatzea",
"Description[fi]": "Ikkunanavigointi",
"Description[fr]": "Navigation parmi les fenêtres",
"Description[gl]": "Navegación polas xanelas.",
"Description[he]": "ניווט בין חלונות",
"Description[hu]": "Navigáció az ablakok között",
"Description[ia]": "Navigation per fenestras",
"Description[id]": "Navigasi Melalui Jendela",
"Description[is]": "Flett á milli glugga",
"Description[it]": "Navigazione tra le finestre",
"Description[ja]": "ウィンドウ間を移動",
"Description[ka]": "ფანჯრებში ნავიგაცია",
"Description[ko]": "창간 탐색",
"Description[lt]": "Naršymas po langus",
"Description[lv]": "Pārvietoties cauri logiem",
"Description[nb]": "Bla gjennom vinduer",
"Description[nl]": "Navigatie door vensters",
"Description[nn]": "Bla gjennom vindauge",
"Description[pl]": "Przełączanie pomiędzy oknami",
"Description[pt]": "Navegação pelas Janelas",
"Description[pt_BR]": "Navegação pelas janelas",
"Description[ro]": "Navigare printre ferestre",
"Description[ru]": "Настройка переключателя окон",
"Description[sa]": "विण्डोजद्वारा नेविगेशनम्",
"Description[sk]": "Navigácia cez okná",
"Description[sl]": "Krmarjenje med okni",
"Description[sv]": "Navigering via fönster",
"Description[ta]": "சாளரங்களுக்கிடையே உலாவல்",
"Description[tr]": "Pencereler Arası Dolaşım",
"Description[uk]": "Навігація вікнами",
"Description[vi]": "Điều hướng qua các cửa sổ",
"Description[x-test]": "xxNavigation Through Windowsxx",
"Description[zh_CN]": "配置窗口切换器选项",
"Description[zh_TW]": "在視窗間探索",
"Icon": "preferences-system-tabbox",
"Name": "Task Switcher",
"Name[ar]": "مبدّل المهام",
"Name[az]": "Tapşırıq dəyişdirici",
"Name[be]": "Сродак пераключэння задач",
"Name[bg]": "Превключване на задачи",
"Name[ca@valencia]": "Commutador de tasques",
"Name[ca]": "Commutador de tasques",
"Name[cs]": "Přepínač úloh",
"Name[da]": "Opgaveskifter",
"Name[de]": "Anwendungsumschalter",
"Name[en_GB]": "Task Switcher",
"Name[eo]": "Taskŝanĝilo",
"Name[es]": "Selector de tareas",
"Name[et]": "Ülesannete vahetaja",
"Name[eu]": "Ataza-trukatzailea",
"Name[fi]": "Tehtävävaihto",
"Name[fr]": "Sélecteur de tâches",
"Name[gl]": "Selector de tarefa",
"Name[he]": "מחליף משימות",
"Name[hu]": "Feladatváltó",
"Name[ia]": "Commutator de carga",
"Name[id]": "Pengalih Tugas",
"Name[is]": "Verkefnaskiptir",
"Name[it]": "Selettore delle attività",
"Name[ja]": "タスクスイッチャー",
"Name[ka]": "ამოცანების გადამრთველი",
"Name[ko]": "작업 전환기",
"Name[lt]": "Užduočių perjungiklis",
"Name[lv]": "Uzdevumu pārslēdzējs",
"Name[nb]": "Oppgavebytter",
"Name[nl]": "Taakschakelaar",
"Name[nn]": "Oppgåve­vekslar",
"Name[pl]": "Przełącznik zadań",
"Name[pt]": "Selector de Tarefas",
"Name[pt_BR]": "Seletor de tarefas",
"Name[ro]": "Comutator de sarcini",
"Name[ru]": "Переключение окон",
"Name[sa]": "कार्य स्विचर",
"Name[sk]": "Prepínač úloh",
"Name[sl]": "Preklopnik opravil",
"Name[sv]": "Aktivitetsbyte",
"Name[ta]": "பணி மாற்றி",
"Name[tr]": "Görev Değiştiricisi",
"Name[uk]": "Перемикання задач",
"Name[vi]": "Trình chuyển tác vụ",
"Name[x-test]": "xxTask Switcherxx",
"Name[zh_CN]": "任务切换器",
"Name[zh_TW]": "工作切換器"
},
"X-DocPath": "kcontrol/kwintabbox/index.html",
"X-KDE-Keywords": "window,windows,switcher,window switcher,switching,window switching,alttab,alt-tab,alt+tab,alt tab,apps changer,application changer,app,task,switch,task switcher",
"X-KDE-Keywords[ar]": "نافذة,نوافذ,مبدل,مبدل نوافذ,تاب,ألت تاب,مغير التطبيقات,مهمة,مهام",
"X-KDE-Keywords[bg]": "прозорец,прозорци,превключвател,превключвател на прозорци,превключване,превключване на прозорци,alttab,alt-tab,alt+tab,alt раздел,смяна на приложения,смяна на приложения,приложение,задача,превключвател,превключвател на задачи",
"X-KDE-Keywords[ca@valencia]": "finestra,finestres,commutador,commutador de finestres,commutació,commutació de finestres,alttab,alt-tab,alt+tab,alt tab,canviador d'aplicacions,canvi d'aplicacions,app,aplicació,tasca,commutador,commutador de tasques",
"X-KDE-Keywords[ca]": "finestra,finestres,commutador,commutador de finestres,commutació,commutació de finestres,alttab,alt-tab,alt+tab,alt tab,canviador d'aplicacions,canvi d'aplicacions,app,aplicació,tasca,commutador,commutador de tasques",
"X-KDE-Keywords[en_GB]": "window,windows,switcher,window switcher,switching,window switching,alttab,alt-tab,alt+tab,alt tab,apps changer,application changer,app,task,switch,task switcher",
"X-KDE-Keywords[es]": "ventana,ventanas,cambiador,selector,selector de ventana,cambiador de ventana,cambio,selección,cambio de ventana,alttab,alt-tab,alt+tab,alt tab,cambiador de aplicaciones,selector de aplicaciones,app,tarea,cambiador de tareas,selector de tareas",
"X-KDE-Keywords[eu]": "leihoa,leihoak,aldarazlea,leiho aldarazlea,aldatzea,leihoa aldatzea,alttab,alt-tab,alt+tab,alt tab,aplikazio aldarazlea,aplikazioa,ataza,aldatu,ataza aldarazlea",
"X-KDE-Keywords[fi]": "ikkuna,ikkunat,vaihto,vaihtaja,vaihtaminen,vaihda,ikkunavaihto,alttab,alt-tab,alt+tab,alt tab,tehtävävaihto,sovellusvaihto,ohjelmavaihto",
"X-KDE-Keywords[fr]": "fenêtre, fenêtres, commutateur, commutateur de fenêtre, changement, changement de fenêtre, alt-tab, alt tab, alt+tab, changement d'applications, changement d'application, commutateur d'applications, basculer, tâche, commutateur, sélecteur de tâches",
"X-KDE-Keywords[gl]": "xanela,xanelas,alternador,cambiar,trocar de xanela,alttab,alt-tab,alt+tab,alt tab,apps changer,cambiador de aplicacións,application changer,app,aplicación,apli,task,tarefa,traballo,switch,cambiar,task switcher,cambiador de tarefa,cambiador de traballo,trocador,trocador de tarefa,trocador de traballo",
"X-KDE-Keywords[he]": "חלון,חלונות,בורר,בורר חלונות,בוחר חלונות,החלפה,מעבר,העברה,החלפת חלונות,מעבר חלונות,alttab,alt-tab,alt+tab,alt tab,בורר יישומים,מחליף יישומים,יישום,משימה,החלפה,בורר משימות",
"X-KDE-Keywords[hu]": "ablak,ablakok,váltó,ablakváltó,váltás,ablakváltás,alttab,alt-tab,alt+tab,alt tab,alkalmazásáváltó,alkalmazás,feladat,vált,feladatváltó",
"X-KDE-Keywords[ia]": "fenestra,fenestras,commutator,commutator de fenestra,commutar,commutar fenestra,alttab,alt-tab,alt+tab,alt tab, modificator de application, app, carga, commuta, commutator de carga",
"X-KDE-Keywords[is]": "gluggi,gluggar,skiptir,gluggaskiptir,skipting,gluggaskipting,alttab,alt-tab,alt+tab,alt tab,forritabreytir,forrit,verkefni,skipta,verkefnaskiptir",
"X-KDE-Keywords[it]": "finestra,finestre,selettore,selettore delle finestre,selezione,selezione delle finestre,alttab,alt-tab,alt+tab,alt tab,selettore delle applicazioni,cambio applicazione,applicazione,attività,selettore delle attività",
"X-KDE-Keywords[ka]": "window,windows,switcher,window switcher,switching,window switching,alttab,alt-tab,alt+tab,alt tab,apps changer,application changer,app,task,switch,task switcher,ფანჯარა,ფანჯრები,ფანჯრის გადართვა,გადართვა,აპები,ამოცანა,ამოცანის გადართვა",
"X-KDE-Keywords[ko]": "창,창 전환,전환기,앱 전환,프로그램 전환,작업,전환,작업 전환기",
"X-KDE-Keywords[lv]": "logs,logi,pārslēdzējs,logu pārslēdzējs,pārslēgšana,logu pārslēgšana,alttab,alt-tab,alt+tab,alt tab,programmu maiņa,programmu mainītājs,lietotne,uzdevums,pārslēgt,uzdevumu pārslēdzējs",
"X-KDE-Keywords[nb]": "vindu,vinduer,bytte,vindusbytter,bytte,vindusbytter,alttab,alt-tab,alt+tab,alt tab,appbytter,programbytter,appveksler,programveksler,app,oppgave,bytte,veksle,oppgavebytter,oppgaveveksler",
"X-KDE-Keywords[nl]": "venster,vensters,wisselaar,vensterwisselaar,omschakelen,wisselen van venter,alttab,alt-tab,alt+tab,alt tab,wisselaar van toepassing,app,taak,schakelaar,takenwisselaar",
"X-KDE-Keywords[nn]": "vindauge,vindauge,byte,vindaugsbytar,byte,vindaugsbytar,alttab,alt-tab,alt+tab,alt tab,appbytar,programbytar,appvekslar,programvekslar,app,oppgåve,byte,veksla,oppgåvebytar,oppgåvevekslar",
"X-KDE-Keywords[pl]": "okno,okna,przełącznik,przełącznik okien,przełączanie,przełączanie okien,alttab,alt-tab,alt+tab,alt tab,zmieniacz apek,zmieniacz aplikacji,aplikacja,zadanie,przełącz,przełącznik zadań",
"X-KDE-Keywords[pt_BR]": "janela,janelas,trocador de janela,trocador de janelas,troca,troca de janela,alttab,alt-tab,alt+tab,alt tab,alterador de aplicativos,alterador de aplicação,aplicativo,tarefa,trocar,trocador de tarefas",
"X-KDE-Keywords[ru]": "window,windows,switcher,window switcher,switching,window switching,alttab,alt-tab,alt+tab,alt tab,apps changer,application changer,app,task,switch,task switcher,окно,окна,переключатель,переключатель окон,переключение,переключение окон,переключатель приложений,приложение,задача,переключить,переключатель задач",
"X-KDE-Keywords[sa]": "विंडो,विंडोज,स्विचर,विंडो स्विचर,स्विचिंग,विंडो स्विचिंग,alttab,alt-टैब,alt+टैब,alt टैब,एप्स चेंजर,एप्लिकेशन चेंजर,एप्लिकेशन,कार्य,स्विच,कार्य स्विचर",
"X-KDE-Keywords[sl]": "okno,okna,preklopnik,preklopnik oken,preklapljanje,preklop oken,alttab,alt-tab,alt+tab,alt zavihek,izmenjevalec aplikacij,izmenjevalnik aplikacij, aplikacija,opravilo,stikalo,preklopnik opravil",
"X-KDE-Keywords[sv]": "fönster,byte,fönsterbyte,alttabulator,alt-tabulator,alt+tabulator,alt tabulator,programbytare,program,aktivitet,aktivitetsbyte",
"X-KDE-Keywords[tr]": "pencere,pencereler,değiştirici,pencere değiştiricisi,değiştirme,alttab,alt-tab,alt+tab,alt tab, uygulama değiştiricisi,uygulama,app,görev,değiştir,görev değiştiricisi,commandtab,command-tab,command+tab,command tab",
"X-KDE-Keywords[uk]": "window,windows,switcher,window switcher,switching,window switching,alttab,alt-tab,alt+tab,alt tab,apps changer,application changer,app,task,switch,task switcher,вікно,вікна,перемикач,перемикач вікон,перемикання,перемикання вікон,альттаб,альт-таб,альт+таб,зміна програм,програма,завдання,перемикання,перемикання завдань",
"X-KDE-Keywords[x-test]": "xxwindowxx,xxwindowsxx,xxswitcherxx,xxwindow switcherxx,xxswitchingxx,xxwindow switchingxx,xxalttabxx,xxalt-tabxx,xxalt+tabxx,xxalt tabxx,xxapps changerxx,xxapplication changerxx,xxappxx,xxtaskxx,xxswitchxx,xxtask switcherxx",
"X-KDE-Keywords[zh_CN]": "window,windows,switcher,window switcher,switching,window switching,alttab,alt-tab,alt+tab,alt tab,apps changer,application changer,app,task,switch,task switcher,chuangkou,qiehuanqi,chuangkouqiehuanqi,qiehuan,chuangkouqiehuan,yingyongqiehuanqi,yingyongchengxuqiehuanqi,yingyong,yingyongchengxu,renwu,renwuqiehuanqi,窗口,切换器,窗口切换器,切换,窗口切换,应用切换器,应用程序切换器,应用,应用程序,任务,任务切换器",
"X-KDE-Keywords[zh_TW]": "視窗,切換器,切換,視窗切換,alttab,應用程式切換,應用程式,程式,工作,工作切換",
"X-KDE-System-Settings-Parent-Category": "windowmanagement",
"X-KDE-Weight": 20
}
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="kwinrc">
<parameter name="EffectGroup"/>
</kcfgfile>
<group name="$(EffectGroup)">
<entry key="TabBox" type="Bool">
<default>false</default>
</entry>
<entry key="TabBoxAlternative" type="Bool">
<default>false</default>
</entry>
</group>
</kcfg>
@@ -0,0 +1,6 @@
File=kwinswitcheffectsettings.kcfg
NameSpace=KWin::TabBox
ClassName=SwitchEffectSettings
Mutators=true
DefaultValueGetters=true
ParentInConstructor=true
@@ -0,0 +1,49 @@
[KNewStuff3]
Name=Task Switcher Styles
Name[ar]=أنماط مبدّل المهام
Name[be]=Стылі для сродку пераключэння задач
Name[bg]=Стилове на превключване на задачи
Name[ca]=Estils del commutador de tasques
Name[ca@valencia]=Estils del commutador de tasques
Name[cs]=Styly přepínače úloh
Name[da]=Opgaveskifterstile
Name[el]=Θέματα εναλλάκτη εργασιών
Name[en_GB]=Task Switcher Styles
Name[eo]=Stiloj de Task-Ŝanĝilo
Name[es]=Estilos del selector de tareas
Name[eu]=Ataza-aldarazlearen estiloak
Name[fi]=Tehtävävaihtotyylit
Name[fr]=Styles du commutateur de tâches
Name[gl]=Estilos de selector de tarefa
Name[he]=סגנונות מחליף משימות
Name[hu]=Feladatváltó stílusok
Name[ia]=Stilos de Commutator de carga
Name[is]=Stílsnið fyrir verkefnaskipti
Name[it]=Stile del selettore delle attività
Name[ka]=ამოცანების გადამრთველის სტილები
Name[ko]=작업 전환기 스타일
Name[lt]=Užduočių perjungiklio stiliai
Name[lv]=Uzdevumu pārslēdzēja stili
Name[nb]=Oppgavebytter-stiler
Name[nl]=Stijlen van taakschakelaar
Name[nn]=Oppgåvevekslar-stilar
Name[pl]=Wyglądy przełącznika zadań
Name[pt_BR]=Estilos do seletor de tarefas
Name[ru]=Стили переключения окон
Name[sa]=कार्य स्विचर शैल्याः
Name[sk]=Štýly prepínača úloh
Name[sl]=Slogi preklopa med opravili
Name[sv]=Stilar för aktivitetsbyte
Name[ta]=பணி மாற்றி வகைகள்
Name[tr]=Görev Değiştiricisi Biçemleri
Name[uk]=Стилі перемикання задач
Name[x-test]=xxTask Switcher Stylesxx
Name[zh_CN]=任务切换器样式
Name[zh_TW]=工作切換器風格
ProvidersUrl=https://autoconfig.kde.org/ocs/providers.xml
ContentWarning=Executables
Categories=Kwin Switching Layouts Plasma 6
StandardResource=tmp
Uncompress=kpackage
KPackageStructure=KWin/WindowSwitcher
@@ -0,0 +1,398 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "kwintabboxconfigform.h"
#include "kwintabboxsettings.h"
#include "shortcutsettings.h"
#include "ui_main.h"
namespace KWin
{
using namespace TabBox;
KWinTabBoxConfigForm::KWinTabBoxConfigForm(TabboxType type, TabBoxSettings *config, ShortcutSettings *shortcutsConfig, QWidget *parent)
: QWidget(parent)
, m_config(config)
, m_shortcuts(shortcutsConfig)
, ui(new Ui::KWinTabBoxConfigForm)
{
ui->setupUi(this);
if (QApplication::screens().count() < 2) {
ui->filterScreens->hide();
ui->screenFilter->hide();
}
connect(this, &KWinTabBoxConfigForm::configChanged, this, &KWinTabBoxConfigForm::updateDefaultIndicators);
connect(ui->effectConfigButton, &QPushButton::clicked, this, &KWinTabBoxConfigForm::effectConfigButtonClicked);
connect(ui->kcfg_ShowTabBox, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::tabBoxToggled);
connect(ui->filterScreens, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterScreen);
connect(ui->currentScreen, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterScreen);
connect(ui->otherScreens, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterScreen);
connect(ui->filterDesktops, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterDesktop);
connect(ui->currentDesktop, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterDesktop);
connect(ui->otherDesktops, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterDesktop);
connect(ui->filterActivities, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterActivites);
connect(ui->currentActivity, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterActivites);
connect(ui->otherActivities, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterActivites);
connect(ui->filterMinimization, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterMinimization);
connect(ui->visibleWindows, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterMinimization);
connect(ui->hiddenWindows, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterMinimization);
connect(ui->oneAppWindow, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onApplicationMode);
connect(ui->orderMinimized, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onOrderMinimizedMode);
connect(ui->showDesktop, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onShowDesktopMode);
connect(ui->switchingModeCombo, &QComboBox::activated, this, &KWinTabBoxConfigForm::onSwitchingMode);
connect(ui->effectCombo, &QComboBox::activated, this, &KWinTabBoxConfigForm::onEffectCombo);
auto initShortcutWidget = [this](KKeySequenceWidget *widget, const char *name) {
widget->setCheckActionCollections({m_shortcuts->actionCollection()});
widget->setProperty("shortcutAction", name);
connect(widget, &KKeySequenceWidget::keySequenceChanged, this, &KWinTabBoxConfigForm::onShortcutChanged);
};
if (TabboxType::Main == type) {
initShortcutWidget(ui->scAll, "Walk Through Windows");
initShortcutWidget(ui->scAllReverse, "Walk Through Windows (Reverse)");
initShortcutWidget(ui->scCurrent, "Walk Through Windows of Current Application");
initShortcutWidget(ui->scCurrentReverse, "Walk Through Windows of Current Application (Reverse)");
} else if (TabboxType::Alternative == type) {
initShortcutWidget(ui->scAll, "Walk Through Windows Alternative");
initShortcutWidget(ui->scAllReverse, "Walk Through Windows Alternative (Reverse)");
initShortcutWidget(ui->scCurrent, "Walk Through Windows of Current Application Alternative");
initShortcutWidget(ui->scCurrentReverse, "Walk Through Windows of Current Application Alternative (Reverse)");
}
updateUiFromConfig();
}
KWinTabBoxConfigForm::~KWinTabBoxConfigForm()
{
delete ui;
}
TabBoxSettings *KWinTabBoxConfigForm::config() const
{
return m_config;
}
bool KWinTabBoxConfigForm::highlightWindows() const
{
return ui->kcfg_HighlightWindows->isChecked();
}
bool KWinTabBoxConfigForm::showTabBox() const
{
return ui->kcfg_ShowTabBox->isChecked();
}
int KWinTabBoxConfigForm::filterScreen() const
{
if (ui->filterScreens->isChecked()) {
return ui->currentScreen->isChecked() ? TabBoxConfig::OnlyCurrentScreenClients : TabBoxConfig::ExcludeCurrentScreenClients;
} else {
return TabBoxConfig::IgnoreMultiScreen;
}
}
int KWinTabBoxConfigForm::filterDesktop() const
{
if (ui->filterDesktops->isChecked()) {
return ui->currentDesktop->isChecked() ? TabBoxConfig::OnlyCurrentDesktopClients : TabBoxConfig::ExcludeCurrentDesktopClients;
} else {
return TabBoxConfig::AllDesktopsClients;
}
}
int KWinTabBoxConfigForm::filterActivities() const
{
if (ui->filterActivities->isChecked()) {
return ui->currentActivity->isChecked() ? TabBoxConfig::OnlyCurrentActivityClients : TabBoxConfig::ExcludeCurrentActivityClients;
} else {
return TabBoxConfig::AllActivitiesClients;
}
}
int KWinTabBoxConfigForm::filterMinimization() const
{
if (ui->filterMinimization->isChecked()) {
return ui->visibleWindows->isChecked() ? TabBoxConfig::ExcludeMinimizedClients : TabBoxConfig::OnlyMinimizedClients;
} else {
return TabBoxConfig::IgnoreMinimizedStatus;
}
}
int KWinTabBoxConfigForm::applicationMode() const
{
return ui->oneAppWindow->isChecked() ? TabBoxConfig::OneWindowPerApplication : TabBoxConfig::AllWindowsAllApplications;
}
int KWinTabBoxConfigForm::orderMinimizedMode() const
{
return ui->orderMinimized->isChecked() ? TabBoxConfig::GroupByMinimized : TabBoxConfig::NoGroupByMinimized;
}
int KWinTabBoxConfigForm::showDesktopMode() const
{
return ui->showDesktop->isChecked() ? TabBoxConfig::ShowDesktopClient : TabBoxConfig::DoNotShowDesktopClient;
}
int KWinTabBoxConfigForm::switchingMode() const
{
return ui->switchingModeCombo->currentIndex();
}
QString KWinTabBoxConfigForm::layoutName() const
{
return ui->effectCombo->currentData().toString();
}
void KWinTabBoxConfigForm::setFilterScreen(TabBox::TabBoxConfig::ClientMultiScreenMode mode)
{
ui->filterScreens->setChecked(mode != TabBoxConfig::IgnoreMultiScreen);
ui->currentScreen->setChecked(mode == TabBoxConfig::OnlyCurrentScreenClients);
ui->otherScreens->setChecked(mode == TabBoxConfig::ExcludeCurrentScreenClients);
}
void KWinTabBoxConfigForm::setFilterDesktop(TabBox::TabBoxConfig::ClientDesktopMode mode)
{
ui->filterDesktops->setChecked(mode != TabBoxConfig::AllDesktopsClients);
ui->currentDesktop->setChecked(mode == TabBoxConfig::OnlyCurrentDesktopClients);
ui->otherDesktops->setChecked(mode == TabBoxConfig::ExcludeCurrentDesktopClients);
}
void KWinTabBoxConfigForm::setFilterActivities(TabBox::TabBoxConfig::ClientActivitiesMode mode)
{
ui->filterActivities->setChecked(mode != TabBoxConfig::AllActivitiesClients);
ui->currentActivity->setChecked(mode == TabBoxConfig::OnlyCurrentActivityClients);
ui->otherActivities->setChecked(mode == TabBoxConfig::ExcludeCurrentActivityClients);
}
void KWinTabBoxConfigForm::setFilterMinimization(TabBox::TabBoxConfig::ClientMinimizedMode mode)
{
ui->filterMinimization->setChecked(mode != TabBoxConfig::IgnoreMinimizedStatus);
ui->visibleWindows->setChecked(mode == TabBoxConfig::ExcludeMinimizedClients);
ui->hiddenWindows->setChecked(mode == TabBoxConfig::OnlyMinimizedClients);
}
void KWinTabBoxConfigForm::setApplicationMode(TabBox::TabBoxConfig::ClientApplicationsMode mode)
{
ui->oneAppWindow->setChecked(mode == TabBoxConfig::OneWindowPerApplication);
}
void KWinTabBoxConfigForm::setOrderMinimizedMode(TabBox::TabBoxConfig::OrderMinimizedMode mode)
{
ui->orderMinimized->setChecked(mode == TabBoxConfig::GroupByMinimized);
}
void KWinTabBoxConfigForm::setShowDesktopMode(TabBox::TabBoxConfig::ShowDesktopMode mode)
{
ui->showDesktop->setChecked(mode == TabBoxConfig::ShowDesktopClient);
}
void KWinTabBoxConfigForm::setSwitchingModeChanged(TabBox::TabBoxConfig::ClientSwitchingMode mode)
{
ui->switchingModeCombo->setCurrentIndex(mode);
}
void KWinTabBoxConfigForm::setLayoutName(const QString &layoutName)
{
const int index = ui->effectCombo->findData(layoutName);
if (index >= 0) {
ui->effectCombo->setCurrentIndex(index);
}
}
void KWinTabBoxConfigForm::setEffectComboModel(QStandardItemModel *model)
{
// We don't want to lose the config layout when resetting the combo model
const QString layout = m_config->layoutName();
ui->effectCombo->setModel(model);
setLayoutName(layout);
}
QVariant KWinTabBoxConfigForm::effectComboCurrentData(int role) const
{
return ui->effectCombo->currentData(role);
}
void KWinTabBoxConfigForm::tabBoxToggled(bool on)
{
// Highlight Windows options is availabled if no TabBox effect is selected
// or if Tabbox is not builtin effet.
on = !on || ui->effectCombo->currentData(AddonEffect).toBool();
ui->kcfg_HighlightWindows->setEnabled(on && m_isHighlightWindowsEnabled);
}
void KWinTabBoxConfigForm::onFilterScreen()
{
m_config->setMultiScreenMode(filterScreen());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onFilterDesktop()
{
m_config->setDesktopMode(filterDesktop());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onFilterActivites()
{
m_config->setActivitiesMode(filterActivities());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onFilterMinimization()
{
m_config->setMinimizedMode(filterMinimization());
Q_EMIT configChanged();
}
void KWin::KWinTabBoxConfigForm::onApplicationMode()
{
m_config->setApplicationsMode(applicationMode());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onOrderMinimizedMode()
{
m_config->setOrderMinimizedMode(orderMinimizedMode());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onShowDesktopMode()
{
m_config->setShowDesktopMode(showDesktopMode());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onSwitchingMode()
{
m_config->setSwitchingMode(switchingMode());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onEffectCombo()
{
const bool isAddonEffect = ui->effectCombo->currentData(AddonEffect).toBool();
ui->effectConfigButton->setIcon(QIcon::fromTheme(isAddonEffect ? "view-preview" : "configure"));
if (!ui->kcfg_ShowTabBox->isChecked()) {
return;
}
ui->kcfg_HighlightWindows->setEnabled(isAddonEffect && m_isHighlightWindowsEnabled);
m_config->setLayoutName(layoutName());
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::onShortcutChanged(const QKeySequence &seq)
{
const QString actionName = sender()->property("shortcutAction").toString();
m_shortcuts->setShortcut(actionName, seq);
Q_EMIT configChanged();
}
void KWinTabBoxConfigForm::updateUiFromConfig()
{
setFilterScreen(static_cast<TabBoxConfig::ClientMultiScreenMode>(m_config->multiScreenMode()));
setFilterDesktop(static_cast<TabBoxConfig::ClientDesktopMode>(m_config->desktopMode()));
setFilterActivities(static_cast<TabBoxConfig::ClientActivitiesMode>(m_config->activitiesMode()));
setFilterMinimization(static_cast<TabBoxConfig::ClientMinimizedMode>(m_config->minimizedMode()));
setApplicationMode(static_cast<TabBoxConfig::ClientApplicationsMode>(m_config->applicationsMode()));
setOrderMinimizedMode(static_cast<TabBoxConfig::OrderMinimizedMode>(m_config->orderMinimizedMode()));
setShowDesktopMode(static_cast<TabBoxConfig::ShowDesktopMode>(m_config->showDesktopMode()));
setSwitchingModeChanged(static_cast<TabBoxConfig::ClientSwitchingMode>(m_config->switchingMode()));
setLayoutName(m_config->layoutName());
for (const auto &widget : {ui->scAll, ui->scAllReverse, ui->scCurrent, ui->scCurrentReverse}) {
const QString actionName = widget->property("shortcutAction").toString();
widget->setKeySequence(m_shortcuts->shortcut(actionName));
}
updateDefaultIndicators();
}
void KWinTabBoxConfigForm::setEnabledUi()
{
m_isHighlightWindowsEnabled = !m_config->isHighlightWindowsImmutable();
ui->kcfg_HighlightWindows->setEnabled(!m_config->isHighlightWindowsImmutable());
ui->filterScreens->setEnabled(!m_config->isMultiScreenModeImmutable());
ui->currentScreen->setEnabled(!m_config->isMultiScreenModeImmutable());
ui->otherScreens->setEnabled(!m_config->isMultiScreenModeImmutable());
ui->filterDesktops->setEnabled(!m_config->isDesktopModeImmutable());
ui->currentDesktop->setEnabled(!m_config->isDesktopModeImmutable());
ui->otherDesktops->setEnabled(!m_config->isDesktopModeImmutable());
ui->filterActivities->setEnabled(!m_config->isActivitiesModeImmutable());
ui->currentActivity->setEnabled(!m_config->isActivitiesModeImmutable());
ui->otherActivities->setEnabled(!m_config->isActivitiesModeImmutable());
ui->filterMinimization->setEnabled(!m_config->isMinimizedModeImmutable());
ui->visibleWindows->setEnabled(!m_config->isMinimizedModeImmutable());
ui->hiddenWindows->setEnabled(!m_config->isMinimizedModeImmutable());
ui->oneAppWindow->setEnabled(!m_config->isApplicationsModeImmutable());
ui->orderMinimized->setEnabled(!m_config->isOrderMinimizedModeImmutable());
ui->showDesktop->setEnabled(!m_config->isShowDesktopModeImmutable());
ui->switchingModeCombo->setEnabled(!m_config->isSwitchingModeImmutable());
ui->effectCombo->setEnabled(!m_config->isLayoutNameImmutable());
}
void KWinTabBoxConfigForm::setDefaultIndicatorVisible(bool show)
{
m_showDefaultIndicator = show;
updateDefaultIndicators();
}
void KWinTabBoxConfigForm::updateDefaultIndicators()
{
applyDefaultIndicator({ui->filterScreens, ui->currentScreen, ui->otherScreens},
m_config->multiScreenMode() == m_config->defaultMultiScreenModeValue());
applyDefaultIndicator({ui->filterDesktops, ui->currentDesktop, ui->otherDesktops},
m_config->desktopMode() == m_config->defaultDesktopModeValue());
applyDefaultIndicator({ui->filterActivities, ui->currentActivity, ui->otherActivities},
m_config->activitiesMode() == m_config->defaultActivitiesModeValue());
applyDefaultIndicator({ui->filterMinimization, ui->visibleWindows, ui->hiddenWindows},
m_config->minimizedMode() == m_config->defaultMinimizedModeValue());
applyDefaultIndicator({ui->oneAppWindow}, m_config->applicationsMode() == m_config->defaultApplicationsModeValue());
applyDefaultIndicator({ui->orderMinimized}, m_config->orderMinimizedMode() == m_config->defaultOrderMinimizedModeValue());
applyDefaultIndicator({ui->showDesktop}, m_config->showDesktopMode() == m_config->defaultShowDesktopModeValue());
applyDefaultIndicator({ui->switchingModeCombo}, m_config->switchingMode() == m_config->defaultSwitchingModeValue());
applyDefaultIndicator({ui->effectCombo}, m_config->layoutName() == m_config->defaultLayoutNameValue());
for (const auto &widget : {ui->scAll, ui->scAllReverse, ui->scCurrent, ui->scCurrentReverse}) {
const QString actionName = widget->property("shortcutAction").toString();
applyDefaultIndicator({widget}, m_shortcuts->isDefault(actionName));
}
}
void KWinTabBoxConfigForm::applyDefaultIndicator(QList<QWidget *> widgets, bool isDefault)
{
for (auto widget : widgets) {
widget->setProperty("_kde_highlight_neutral", m_showDefaultIndicator && !isDefault);
widget->update();
}
}
} // namespace
#include "moc_kwintabboxconfigform.cpp"
@@ -0,0 +1,115 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QStandardItemModel>
#include <QWidget>
#include "tabbox/tabboxconfig.h"
namespace Ui
{
class KWinTabBoxConfigForm;
}
namespace KWin
{
namespace TabBox
{
class TabBoxSettings;
class ShortcutSettings;
}
class KWinTabBoxConfigForm : public QWidget
{
Q_OBJECT
public:
enum class TabboxType {
Main,
Alternative,
};
enum EffectComboRole {
LayoutPath = Qt::UserRole + 1,
AddonEffect, // i.e not builtin effects
};
explicit KWinTabBoxConfigForm(TabboxType type, TabBox::TabBoxSettings *config, TabBox::ShortcutSettings *shortcutsConfig, QWidget *parent = nullptr);
~KWinTabBoxConfigForm() override;
TabBox::TabBoxSettings *config() const;
bool highlightWindows() const;
void updateUiFromConfig();
void setDefaultIndicatorVisible(bool visible);
// EffectCombo Data Model
void setEffectComboModel(QStandardItemModel *model);
QVariant effectComboCurrentData(int role = Qt::UserRole) const;
Q_SIGNALS:
void configChanged();
void effectConfigButtonClicked();
private Q_SLOTS:
void tabBoxToggled(bool on);
void onFilterScreen();
void onFilterDesktop();
void onFilterActivites();
void onFilterMinimization();
void onApplicationMode();
void onOrderMinimizedMode();
void onShowDesktopMode();
void onSwitchingMode();
void onEffectCombo();
void onShortcutChanged(const QKeySequence &seq);
void updateDefaultIndicators();
private:
void setEnabledUi();
void applyDefaultIndicator(QList<QWidget *> widgets, bool visible);
// UI property getters
bool showTabBox() const;
int filterScreen() const;
int filterDesktop() const;
int filterActivities() const;
int filterMinimization() const;
int applicationMode() const;
int orderMinimizedMode() const;
int showDesktopMode() const;
int switchingMode() const;
QString layoutName() const;
// UI property setters
void setFilterScreen(TabBox::TabBoxConfig::ClientMultiScreenMode mode);
void setFilterDesktop(TabBox::TabBoxConfig::ClientDesktopMode mode);
void setFilterActivities(TabBox::TabBoxConfig::ClientActivitiesMode mode);
void setFilterMinimization(TabBox::TabBoxConfig::ClientMinimizedMode mode);
void setApplicationMode(TabBox::TabBoxConfig::ClientApplicationsMode mode);
void setOrderMinimizedMode(TabBox::TabBoxConfig::OrderMinimizedMode mode);
void setShowDesktopMode(TabBox::TabBoxConfig::ShowDesktopMode mode);
void setSwitchingModeChanged(TabBox::TabBoxConfig::ClientSwitchingMode mode);
void setLayoutName(const QString &layoutName);
private:
TabBox::TabBoxSettings *m_config = nullptr;
TabBox::ShortcutSettings *m_shortcuts = nullptr;
bool m_showDefaultIndicator = false;
bool m_isHighlightWindowsEnabled = true;
Ui::KWinTabBoxConfigForm *ui;
};
} // namespace
@@ -0,0 +1,49 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "kwintabboxdata.h"
#include "kwinswitcheffectsettings.h"
#include "kwintabboxsettings.h"
#include "shortcutsettings.h"
namespace KWin
{
namespace TabBox
{
KWinTabboxData::KWinTabboxData(QObject *parent)
: KCModuleData(parent)
, m_tabBoxConfig(new TabBoxSettings(QStringLiteral("TabBox"), this))
, m_tabBoxAlternativeConfig(new TabBoxSettings(QStringLiteral("TabBoxAlternative"), this))
, m_shortcutConfig(new ShortcutSettings(this))
{
registerSkeleton(m_tabBoxConfig);
registerSkeleton(m_tabBoxAlternativeConfig);
registerSkeleton(m_shortcutConfig);
}
TabBoxSettings *KWinTabboxData::tabBoxConfig() const
{
return m_tabBoxConfig;
}
TabBoxSettings *KWinTabboxData::tabBoxAlternativeConfig() const
{
return m_tabBoxAlternativeConfig;
}
ShortcutSettings *KWinTabboxData::shortcutConfig() const
{
return m_shortcutConfig;
}
}
}
#include "moc_kwintabboxdata.cpp"
@@ -0,0 +1,43 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QObject>
#include <KCModuleData>
namespace KWin
{
namespace TabBox
{
class TabBoxSettings;
class SwitchEffectSettings;
class ShortcutSettings;
class KWinTabboxData : public KCModuleData
{
Q_OBJECT
public:
explicit KWinTabboxData(QObject *parent);
TabBoxSettings *tabBoxConfig() const;
TabBoxSettings *tabBoxAlternativeConfig() const;
ShortcutSettings *shortcutConfig() const;
private:
TabBoxSettings *m_tabBoxConfig;
TabBoxSettings *m_tabBoxAlternativeConfig;
ShortcutSettings *m_shortcutConfig;
};
}
}
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="kwinrc">
<parameter name="TabBoxGroup"/>
</kcfgfile>
<group name="$(TabBoxGroup)">
<entry key="DesktopMode" type="Int">
<default code="true">TabBoxConfig::defaultDesktopMode()</default>
</entry>
<entry key="ActivitiesMode" type="Int">
<default code="true">TabBoxConfig::defaultActivitiesMode()</default>
</entry>
<entry key="ApplicationsMode" type="Int">
<default code="true">TabBoxConfig::defaultApplicationsMode()</default>
</entry>
<entry key="OrderMinimizedMode" type="Int">
<default code="true">TabBoxConfig::defaultOrderMinimizedMode()</default>
</entry>
<entry key="MinimizedMode" type="Int">
<default code="true">TabBoxConfig::defaultMinimizedMode()</default>
</entry>
<entry key="ShowDesktopMode" type="Int">
<default code="true">TabBoxConfig::defaultShowDesktopMode()</default>
</entry>
<entry key="MultiScreenMode" type="Int">
<default code="true">TabBoxConfig::defaultMultiScreenMode()</default>
</entry>
<entry key="SwitchingMode" type="Int">
<default code="true">TabBoxConfig::defaultSwitchingMode()</default>
</entry>
<entry key="LayoutName" type="String">
<default code="true">TabBoxConfig::defaultLayoutName()</default>
</entry>
<entry key="ShowTabBox" type="Bool">
<default code="true">TabBoxConfig::defaultShowTabBox()</default>
</entry>
<entry key="HighlightWindows" type="Bool">
<default code="true">TabBoxConfig::defaultHighlightWindow()</default>
</entry>
</group>
</kcfg>
@@ -0,0 +1,7 @@
File=kwintabboxsettings.kcfg
NameSpace=KWin::TabBox
ClassName=TabBoxSettings
IncludeFiles=\"tabbox/tabboxconfig.h\"
Mutators=true
DefaultValueGetters=true
ParentInConstructor=true
@@ -0,0 +1,278 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2009, 2011 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
// own
#include "layoutpreview.h"
#include <KApplicationTrader>
#include <KConfigGroup>
#include <KDesktopFile>
#include <KLocalizedString>
#include <QApplication>
#include <QDebug>
#include <QQmlContext>
#include <QQmlEngine>
#include <QScreen>
#include <QStandardPaths>
namespace KWin
{
namespace TabBox
{
LayoutPreview::LayoutPreview(const QString &path, bool showDesktopThumbnail, QObject *parent)
: QObject(parent)
, m_item(nullptr)
{
QQmlEngine *engine = new QQmlEngine(this);
QQmlComponent *component = new QQmlComponent(engine, this);
qmlRegisterType<WindowThumbnailItem>("org.kde.kwin", 3, 0, "WindowThumbnail");
qmlRegisterType<SwitcherItem>("org.kde.kwin", 3, 0, "TabBoxSwitcher");
qmlRegisterType<DesktopBackground>("org.kde.kwin", 3, 0, "DesktopBackground");
qmlRegisterAnonymousType<QAbstractItemModel>("org.kde.kwin", 3);
component->loadUrl(QUrl::fromLocalFile(path));
if (component->isError()) {
qDebug() << component->errorString();
}
QObject *item = component->create();
auto findSwitcher = [item]() -> SwitcherItem * {
if (!item) {
return nullptr;
}
if (SwitcherItem *i = qobject_cast<SwitcherItem *>(item)) {
return i;
} else if (QQuickWindow *w = qobject_cast<QQuickWindow *>(item)) {
return w->contentItem()->findChild<SwitcherItem *>();
}
return item->findChild<SwitcherItem *>();
};
if (SwitcherItem *switcher = findSwitcher()) {
m_item = switcher;
static_cast<ExampleClientModel *>(switcher->model())->showDesktopThumbnail(showDesktopThumbnail);
switcher->setVisible(true);
}
auto findWindow = [item]() -> QQuickWindow * {
if (!item) {
return nullptr;
}
if (QQuickWindow *w = qobject_cast<QQuickWindow *>(item)) {
return w;
}
return item->findChild<QQuickWindow *>();
};
if (QQuickWindow *w = findWindow()) {
w->setKeyboardGrabEnabled(true);
w->installEventFilter(this);
}
}
LayoutPreview::~LayoutPreview()
{
}
bool LayoutPreview::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Escape || keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Space) {
object->deleteLater();
deleteLater();
}
if (m_item && keyEvent->key() == Qt::Key_Tab) {
m_item->incrementIndex();
}
if (m_item && keyEvent->key() == Qt::Key_Backtab) {
m_item->decrementIndex();
}
} else if (event->type() == QEvent::FocusOut) {
object->deleteLater();
deleteLater();
}
return QObject::eventFilter(object, event);
}
ExampleClientModel::ExampleClientModel(QObject *parent)
: QAbstractListModel(parent)
{
init();
}
ExampleClientModel::~ExampleClientModel()
{
}
void ExampleClientModel::init()
{
if (const auto s = KApplicationTrader::preferredService(QStringLiteral("inode/directory"))) {
m_thumbnails << ThumbnailInfo{WindowThumbnailItem::Dolphin, s->name(), s->icon()};
}
if (const auto s = KApplicationTrader::preferredService(QStringLiteral("text/html"))) {
m_thumbnails << ThumbnailInfo{WindowThumbnailItem::Konqueror, s->name(), s->icon()};
}
if (const auto s = KApplicationTrader::preferredService(QStringLiteral("message/rfc822"))) {
m_thumbnails << ThumbnailInfo{WindowThumbnailItem::KMail, s->name(), s->icon()};
}
if (const auto s = KService::serviceByDesktopName(QStringLiteral("kdesystemsettings"))) {
m_thumbnails << ThumbnailInfo{WindowThumbnailItem::Systemsettings, s->name(), s->icon()};
}
}
void ExampleClientModel::showDesktopThumbnail(bool showDesktop)
{
const ThumbnailInfo desktopThumbnail = ThumbnailInfo{WindowThumbnailItem::Desktop, i18n("Show Desktop"), QStringLiteral("desktop")};
const int desktopIndex = m_thumbnails.indexOf(desktopThumbnail);
if (showDesktop == (desktopIndex >= 0)) {
return;
}
Q_EMIT beginResetModel();
if (showDesktop) {
m_thumbnails << desktopThumbnail;
} else {
m_thumbnails.removeAt(desktopIndex);
}
Q_EMIT endResetModel();
}
QVariant ExampleClientModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= rowCount()) {
return QVariant();
}
const ThumbnailInfo &item = m_thumbnails.at(index.row());
switch (role) {
case Qt::DisplayRole:
case CaptionRole:
return item.caption;
case MinimizedRole:
return false;
case DesktopNameRole:
return i18nc("An example Desktop Name", "Desktop 1");
case IconRole:
return item.icon;
case WindowIdRole:
return item.wId;
case CloseableRole:
return item.wId != WindowThumbnailItem::Desktop;
}
return QVariant();
}
QString ExampleClientModel::longestCaption() const
{
QString caption;
for (const auto &item : m_thumbnails) {
if (item.caption.size() > caption.size()) {
caption = item.caption;
}
}
return caption;
}
int ExampleClientModel::rowCount(const QModelIndex &parent) const
{
return m_thumbnails.size();
}
QHash<int, QByteArray> ExampleClientModel::roleNames() const
{
return {
{CaptionRole, QByteArrayLiteral("caption")},
{MinimizedRole, QByteArrayLiteral("minimized")},
{DesktopNameRole, QByteArrayLiteral("desktopName")},
{IconRole, QByteArrayLiteral("icon")},
{WindowIdRole, QByteArrayLiteral("windowId")},
{CloseableRole, QByteArrayLiteral("closeable")},
};
}
SwitcherItem::SwitcherItem(QObject *parent)
: QObject(parent)
, m_model(new ExampleClientModel(this))
, m_item(nullptr)
, m_currentIndex(0)
, m_visible(false)
{
}
SwitcherItem::~SwitcherItem()
{
}
void SwitcherItem::setVisible(bool visible)
{
if (m_visible == visible) {
return;
}
m_visible = visible;
Q_EMIT visibleChanged();
}
void SwitcherItem::setItem(QObject *item)
{
m_item = item;
Q_EMIT itemChanged();
}
void SwitcherItem::setCurrentIndex(int index)
{
if (m_currentIndex == index) {
return;
}
m_currentIndex = index;
Q_EMIT currentIndexChanged(m_currentIndex);
}
QRect SwitcherItem::screenGeometry() const
{
const QScreen *primaryScreen = qApp->primaryScreen();
return primaryScreen->geometry();
}
void SwitcherItem::incrementIndex()
{
setCurrentIndex((m_currentIndex + 1) % m_model->rowCount());
}
void SwitcherItem::decrementIndex()
{
int index = m_currentIndex - 1;
if (index < 0) {
index = m_model->rowCount() - 1;
}
setCurrentIndex(index);
}
DesktopBackground::DesktopBackground(QQuickItem *parent)
: WindowThumbnailItem(parent)
{
setWId(WindowThumbnailItem::Desktop);
connect(this, &QQuickItem::windowChanged, this, &DesktopBackground::stretchToScreen);
stretchToScreen();
};
void DesktopBackground::stretchToScreen()
{
const QQuickWindow *w = window();
if (!w) {
return;
}
const QScreen *screen = w->screen();
if (!screen) {
return;
}
setImplicitSize(screen->size().width(), screen->size().height());
};
} // namespace KWin
} // namespace TabBox
#include "moc_layoutpreview.cpp"
@@ -0,0 +1,174 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2009, 2011 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QAbstractListModel>
#include <QQuickView>
#include <QRect>
#include "thumbnailitem.h"
namespace KWin
{
namespace TabBox
{
class SwitcherItem;
class LayoutPreview : public QObject
{
Q_OBJECT
public:
explicit LayoutPreview(const QString &path, bool showDesktopThumbnail = false, QObject *parent = nullptr);
~LayoutPreview() override;
bool eventFilter(QObject *object, QEvent *event) override;
private:
SwitcherItem *m_item;
};
class ExampleClientModel : public QAbstractListModel
{
Q_OBJECT
public:
enum {
CaptionRole = Qt::UserRole + 1,
MinimizedRole,
DesktopNameRole,
IconRole,
WindowIdRole,
CloseableRole,
};
explicit ExampleClientModel(QObject *parent = nullptr);
~ExampleClientModel() override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE QString longestCaption() const;
void showDesktopThumbnail(bool showDesktop);
private:
struct ThumbnailInfo
{
WindowThumbnailItem::Thumbnail wId;
QString caption;
QString icon;
bool operator==(const ThumbnailInfo &other) const
{
return wId == other.wId;
}
};
void init();
QList<ThumbnailInfo> m_thumbnails;
};
class SwitcherItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QAbstractItemModel *model READ model NOTIFY modelChanged)
Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged)
Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged)
Q_PROPERTY(bool allDesktops READ isAllDesktops NOTIFY allDesktopsChanged)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
/**
* The main QML item that will be displayed in the Dialog
*/
Q_PROPERTY(QObject *item READ item WRITE setItem NOTIFY itemChanged)
Q_CLASSINFO("DefaultProperty", "item")
public:
SwitcherItem(QObject *parent = nullptr);
~SwitcherItem() override;
QAbstractItemModel *model() const;
QRect screenGeometry() const;
bool isVisible() const;
bool isAllDesktops() const;
int currentIndex() const;
void setCurrentIndex(int index);
QObject *item() const;
void setItem(QObject *item);
void setVisible(bool visible);
void incrementIndex();
void decrementIndex();
Q_SIGNALS:
void visibleChanged();
void currentIndexChanged(int index);
void modelChanged();
void allDesktopsChanged();
void screenGeometryChanged();
void itemChanged();
void aboutToShow();
void aboutToHide();
private:
QAbstractItemModel *m_model;
QObject *m_item;
int m_currentIndex;
bool m_visible;
};
inline QAbstractItemModel *SwitcherItem::model() const
{
return m_model;
}
inline bool SwitcherItem::isVisible() const
{
return m_visible;
}
inline bool SwitcherItem::isAllDesktops() const
{
return true;
}
inline int SwitcherItem::currentIndex() const
{
return m_currentIndex;
}
inline QObject *SwitcherItem::item() const
{
return m_item;
}
class DesktopBackground : public WindowThumbnailItem
{
Q_OBJECT
Q_PROPERTY(QVariant activity MEMBER m_activity)
Q_PROPERTY(QVariant desktop MEMBER m_desktop)
Q_PROPERTY(QString outputName MEMBER m_outputName)
public:
DesktopBackground(QQuickItem *parent = nullptr);
private Q_SLOTS:
void stretchToScreen();
private:
// Just for mock-up purposes.
QVariant m_activity;
QVariant m_desktop;
QString m_outputName;
};
} // namespace TabBox
} // namespace KWin
@@ -0,0 +1,280 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "main.h"
#include <kwin_effects_interface.h>
// Qt
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDialog>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QPointer>
#include <QPushButton>
#include <QSpacerItem>
#include <QStandardItemModel>
#include <QStandardPaths>
#include <QStyle>
#include <QTabWidget>
#include <QVBoxLayout>
// KDE
#include <KLocalizedString>
#include <KNSWidgets/Button>
#include <KPluginFactory>
#include <KSeparator>
#include <KTitleWidget>
// Plasma
#include <KPackage/Package>
#include <KPackage/PackageLoader>
// own
#include "kwintabboxconfigform.h"
#include "kwintabboxdata.h"
#include "kwintabboxsettings.h"
#include "layoutpreview.h"
#include "shortcutsettings.h"
#include <QTabBar>
K_PLUGIN_FACTORY_WITH_JSON(KWinTabBoxConfigFactory, "kcm_kwintabbox.json", registerPlugin<KWin::KWinTabBoxConfig>(); registerPlugin<KWin::TabBox::KWinTabboxData>();)
namespace KWin
{
using namespace TabBox;
KWinTabBoxConfig::KWinTabBoxConfig(QObject *parent, const KPluginMetaData &data)
: KCModule(parent, data)
, m_config(KSharedConfig::openConfig("kwinrc"))
, m_data(new KWinTabboxData(this))
{
QTabWidget *tabWidget = new QTabWidget(widget());
tabWidget->setDocumentMode(true);
tabWidget->tabBar()->setExpanding(true);
m_primaryTabBoxUi = new KWinTabBoxConfigForm(KWinTabBoxConfigForm::TabboxType::Main,
m_data->tabBoxConfig(),
m_data->shortcutConfig(),
tabWidget);
m_alternativeTabBoxUi = new KWinTabBoxConfigForm(KWinTabBoxConfigForm::TabboxType::Alternative,
m_data->tabBoxAlternativeConfig(),
m_data->shortcutConfig(),
tabWidget);
tabWidget->addTab(m_primaryTabBoxUi, i18n("Main"));
tabWidget->addTab(m_alternativeTabBoxUi, i18n("Alternative"));
KNSWidgets::Button *ghnsButton = new KNSWidgets::Button(i18n("Get New Task Switcher Styles…"), QStringLiteral("kwinswitcher.knsrc"), widget());
connect(ghnsButton, &KNSWidgets::Button::dialogFinished, this, [this](auto changedEntries) {
if (!changedEntries.isEmpty()) {
initLayoutLists();
}
});
QHBoxLayout *buttonBar = new QHBoxLayout();
QStyle *style = widget()->style();
buttonBar->setContentsMargins(style->pixelMetric(QStyle::PM_LayoutLeftMargin), 0, style->pixelMetric(QStyle::PM_LayoutRightMargin), style->pixelMetric(QStyle::PM_LayoutBottomMargin));
QSpacerItem *buttonBarSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
buttonBar->addItem(buttonBarSpacer);
buttonBar->addWidget(ghnsButton);
QVBoxLayout *layout = new QVBoxLayout(widget());
layout->setContentsMargins(0, 0, 0, 0);
KTitleWidget *infoLabel = new KTitleWidget(tabWidget);
infoLabel->setText(i18n("Focus policy settings limit the functionality of navigating through windows."),
KTitleWidget::InfoMessage);
infoLabel->setIcon(KTitleWidget::InfoMessage, KTitleWidget::ImageLeft);
layout->addWidget(infoLabel, 0);
layout->addWidget(tabWidget, 1);
KSeparator *separator = new KSeparator();
layout->addWidget(separator);
layout->addLayout(buttonBar);
widget()->setLayout(layout);
addConfig(m_data->tabBoxConfig(), m_primaryTabBoxUi);
addConfig(m_data->tabBoxAlternativeConfig(), m_alternativeTabBoxUi);
initLayoutLists();
createConnections(m_primaryTabBoxUi);
createConnections(m_alternativeTabBoxUi);
// check focus policy - we don't offer configs for unreasonable focus policies
KConfigGroup config(m_config, QStringLiteral("Windows"));
QString policy = config.readEntry("FocusPolicy", "ClickToFocus");
if ((policy == "FocusUnderMouse") || (policy == "FocusStrictlyUnderMouse")) {
tabWidget->setEnabled(false);
infoLabel->show();
} else {
infoLabel->hide();
}
}
KWinTabBoxConfig::~KWinTabBoxConfig()
{
}
static QList<KPackage::Package> availableLnFPackages()
{
QList<KPackage::Package> packages;
QStringList paths;
const QStringList dataPaths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
for (const QString &path : dataPaths) {
QDir dir(path + QLatin1String("/plasma/look-and-feel"));
paths << dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
}
const auto &p = paths;
for (const QString &path : p) {
KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel"));
pkg.setPath(path);
pkg.setFallbackPackage(KPackage::Package());
if (!pkg.filePath("defaults").isEmpty()) {
KSharedConfigPtr conf = KSharedConfig::openConfig(pkg.filePath("defaults"));
KConfigGroup cg = KConfigGroup(conf, QStringLiteral("kwinrc"));
cg = KConfigGroup(&cg, QStringLiteral("WindowSwitcher"));
if (!cg.readEntry("LayoutName", QString()).isEmpty()) {
packages << pkg;
}
}
}
return packages;
}
void KWinTabBoxConfig::initLayoutLists()
{
QList<KPluginMetaData> offers = KPackage::PackageLoader::self()->listPackages("KWin/WindowSwitcher");
QStandardItemModel *model = new QStandardItemModel;
auto addToModel = [model](const QString &name, const QString &pluginId, const QString &path) {
QStandardItem *item = new QStandardItem(name);
item->setData(pluginId, Qt::UserRole);
item->setData(path, KWinTabBoxConfigForm::LayoutPath);
item->setData(true, KWinTabBoxConfigForm::AddonEffect);
model->appendRow(item);
};
const auto lnfPackages = availableLnFPackages();
for (const auto &package : lnfPackages) {
const auto &metaData = package.metadata();
const QString switcherFile = package.filePath("windowswitcher", QStringLiteral("WindowSwitcher.qml"));
if (switcherFile.isEmpty()) {
// Skip lnfs that don't actually ship a switcher
continue;
}
addToModel(metaData.name(), metaData.pluginId(), switcherFile);
}
for (const auto &offer : offers) {
const QString pluginName = offer.pluginId();
const QString scriptFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QLatin1String("kwin/tabbox/") + pluginName + QLatin1String("/contents/ui/main.qml"));
if (scriptFile.isEmpty()) {
qWarning() << "scriptfile is null" << pluginName;
continue;
}
addToModel(offer.name(), pluginName, scriptFile);
}
model->sort(0);
m_primaryTabBoxUi->setEffectComboModel(model);
m_alternativeTabBoxUi->setEffectComboModel(model);
}
void KWinTabBoxConfig::createConnections(KWinTabBoxConfigForm *form)
{
connect(form, &KWinTabBoxConfigForm::effectConfigButtonClicked, this, &KWinTabBoxConfig::configureEffectClicked);
connect(form, &KWinTabBoxConfigForm::configChanged, this, &KWinTabBoxConfig::updateUnmanagedState);
connect(this, &KWinTabBoxConfig::defaultsIndicatorsVisibleChanged, form, [form, this]() {
form->setDefaultIndicatorVisible(defaultsIndicatorsVisible());
});
}
void KWinTabBoxConfig::updateUnmanagedState()
{
const bool isNeedSave = m_data->tabBoxConfig()->isSaveNeeded()
|| m_data->tabBoxAlternativeConfig()->isSaveNeeded()
|| m_data->shortcutConfig()->isSaveNeeded();
unmanagedWidgetChangeState(isNeedSave);
const bool isDefault = m_data->tabBoxConfig()->isDefaults()
&& m_data->tabBoxAlternativeConfig()->isDefaults()
&& m_data->shortcutConfig()->isDefaults();
unmanagedWidgetDefaultState(isDefault);
}
void KWinTabBoxConfig::load()
{
KCModule::load();
m_data->tabBoxConfig()->load();
m_data->tabBoxAlternativeConfig()->load();
m_data->shortcutConfig()->load();
m_primaryTabBoxUi->updateUiFromConfig();
m_alternativeTabBoxUi->updateUiFromConfig();
updateUnmanagedState();
}
void KWinTabBoxConfig::save()
{
m_data->tabBoxConfig()->save();
m_data->tabBoxAlternativeConfig()->save();
m_data->shortcutConfig()->save();
KCModule::save();
updateUnmanagedState();
// Reload KWin.
QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
void KWinTabBoxConfig::defaults()
{
m_data->tabBoxConfig()->setDefaults();
m_data->tabBoxAlternativeConfig()->setDefaults();
m_data->shortcutConfig()->setDefaults();
m_primaryTabBoxUi->updateUiFromConfig();
m_alternativeTabBoxUi->updateUiFromConfig();
KCModule::defaults();
updateUnmanagedState();
}
void KWinTabBoxConfig::configureEffectClicked()
{
auto form = qobject_cast<KWinTabBoxConfigForm *>(sender());
Q_ASSERT(form);
if (form->effectComboCurrentData(KWinTabBoxConfigForm::AddonEffect).toBool()) {
// Show the preview for addon effect
new LayoutPreview(form->effectComboCurrentData(KWinTabBoxConfigForm::LayoutPath).toString(),
form->config()->showDesktopMode(),
this);
}
}
} // namespace
#include "main.moc"
#include "moc_main.cpp"
@@ -0,0 +1,55 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <kcmodule.h>
#include <ksharedconfig.h>
namespace KWin
{
class KWinTabBoxConfigForm;
namespace TabBox
{
class KWinTabboxData;
class TabBoxSettings;
}
class KWinTabBoxConfig : public KCModule
{
Q_OBJECT
public:
explicit KWinTabBoxConfig(QObject *parent, const KPluginMetaData &data);
~KWinTabBoxConfig() override;
public Q_SLOTS:
void save() override;
void load() override;
void defaults() override;
private Q_SLOTS:
void updateUnmanagedState();
void configureEffectClicked();
private:
void initLayoutLists();
void createConnections(KWinTabBoxConfigForm *form);
private:
KWinTabBoxConfigForm *m_primaryTabBoxUi = nullptr;
KWinTabBoxConfigForm *m_alternativeTabBoxUi = nullptr;
KSharedConfigPtr m_config;
TabBox::KWinTabboxData *m_data;
};
} // namespace
@@ -0,0 +1,707 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KWinTabBoxConfigForm</class>
<widget class="QWidget" name="KWinTabBoxConfigForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>658</width>
<height>418</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Content</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0" rowspan="2" colspan="3">
<widget class="QCheckBox" name="showDesktop">
<property name="text">
<string>Include &quot;Show Desktop&quot; entry</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="switchingModeCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Recently used</string>
</property>
</item>
<item>
<property name="text">
<string>Stacking order</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QCheckBox" name="oneAppWindow">
<property name="text">
<string>Only one window per application</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="orderMinimized">
<property name="text">
<string>Order minimized windows after unminimized windows</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Sort order:</string>
</property>
<property name="buddy">
<cstring>switchingModeCombo</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="2" rowspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Filter windows by</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="filterDesktops">
<property name="text">
<string>Virtual desktops</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="desktopFilter" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>24</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="currentDesktop">
<property name="text">
<string>Current desktop</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="otherDesktops">
<property name="text">
<string>All other desktops</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="filterActivities">
<property name="text">
<string>Activities</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="activityFilter" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>24</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="currentActivity">
<property name="text">
<string>Current activity</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="otherActivities">
<property name="text">
<string>All other activities</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="filterScreens">
<property name="text">
<string>Screens</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="screenFilter" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>24</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="currentScreen">
<property name="text">
<string>Current screen</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="otherScreens">
<property name="text">
<string>All other screens</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="filterMinimization">
<property name="text">
<string>Minimization</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="minimizationFilter" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>24</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="visibleWindows">
<property name="text">
<string>Visible windows</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="hiddenWindows">
<property name="text">
<string>Hidden windows</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" rowspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Shortcuts</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Forward</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>All windows</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Reverse</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Forward</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Reverse</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="KKeySequenceWidget" name="scCurrentReverse" native="true"/>
</item>
<item row="5" column="1" colspan="3">
<widget class="KKeySequenceWidget" name="scCurrent" native="true"/>
</item>
<item row="4" column="0" colspan="4">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Current application</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="KKeySequenceWidget" name="scAllReverse" native="true"/>
</item>
<item row="1" column="1" colspan="3">
<widget class="KKeySequenceWidget" name="scAll" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Visualization</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="1">
<widget class="QWidget" name="widget_6" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="effectCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The effect to replace the list window when desktop effects are active.</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="effectConfigButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset theme="view-preview"/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="kcfg_ShowTabBox">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="kcfg_HighlightWindows">
<property name="toolTip">
<string>The currently selected window will be highlighted by fading out all other windows. This option requires desktop effects to be active.</string>
</property>
<property name="text">
<string>Show selected window</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KKeySequenceWidget</class>
<extends>QWidget</extends>
<header>kkeysequencewidget.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kcfg_HighlightWindows</tabstop>
<tabstop>kcfg_ShowTabBox</tabstop>
<tabstop>effectCombo</tabstop>
<tabstop>effectConfigButton</tabstop>
<tabstop>switchingModeCombo</tabstop>
<tabstop>showDesktop</tabstop>
<tabstop>oneAppWindow</tabstop>
<tabstop>filterDesktops</tabstop>
<tabstop>currentDesktop</tabstop>
<tabstop>otherDesktops</tabstop>
<tabstop>filterActivities</tabstop>
<tabstop>currentActivity</tabstop>
<tabstop>otherActivities</tabstop>
<tabstop>filterScreens</tabstop>
<tabstop>currentScreen</tabstop>
<tabstop>otherScreens</tabstop>
<tabstop>filterMinimization</tabstop>
<tabstop>visibleWindows</tabstop>
<tabstop>hiddenWindows</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>filterDesktops</sender>
<signal>toggled(bool)</signal>
<receiver>desktopFilter</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>541</x>
<y>172</y>
</hint>
<hint type="destinationlabel">
<x>701</x>
<y>197</y>
</hint>
</hints>
</connection>
<connection>
<sender>filterActivities</sender>
<signal>toggled(bool)</signal>
<receiver>activityFilter</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>543</x>
<y>222</y>
</hint>
<hint type="destinationlabel">
<x>701</x>
<y>247</y>
</hint>
</hints>
</connection>
<connection>
<sender>filterScreens</sender>
<signal>toggled(bool)</signal>
<receiver>screenFilter</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>555</x>
<y>272</y>
</hint>
<hint type="destinationlabel">
<x>701</x>
<y>297</y>
</hint>
</hints>
</connection>
<connection>
<sender>filterMinimization</sender>
<signal>toggled(bool)</signal>
<receiver>minimizationFilter</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>558</x>
<y>322</y>
</hint>
<hint type="destinationlabel">
<x>701</x>
<y>347</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_ShowTabBox</sender>
<signal>toggled(bool)</signal>
<receiver>widget_6</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>164</x>
<y>125</y>
</hint>
<hint type="destinationlabel">
<x>230</x>
<y>108</y>
</hint>
</hints>
</connection>
</connections>
</ui>
@@ -0,0 +1,170 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "shortcutsettings.h"
#include <QAction>
#include <KActionCollection>
#include <KGlobalAccel>
#include <KLocalizedString>
// Implementation of a KConfigSkeletonItem that uses KGlobalAccel to retrieve and store
// shortcut settings instead of storing them in a config file
class ShortcutItem : public KConfigSkeletonItem
{
public:
ShortcutItem(QAction *action, KActionCollection *actionCollection);
void readConfig(KConfig *config) override;
void writeConfig(KConfig *config) override;
void readDefault(KConfig *config) override;
void setDefault() override;
void swapDefault() override;
bool isEqual(const QVariant &p) const override;
QVariant property() const override;
void setProperty(const QVariant &p) override;
private:
KActionCollection *m_actionCollection = nullptr;
QAction *m_action = nullptr;
QKeySequence m_savedShortcut;
};
ShortcutItem::ShortcutItem(QAction *action, KActionCollection *actionCollection)
: KConfigSkeletonItem(actionCollection->componentName(), action->text())
, m_actionCollection(actionCollection)
, m_action(action)
{
setGetDefaultImpl([this] {
return m_actionCollection->defaultShortcut(m_action);
});
setIsDefaultImpl([this] {
return m_action->shortcut() == m_actionCollection->defaultShortcut(m_action);
});
setIsSaveNeededImpl([this] {
return (m_action->shortcut() != m_savedShortcut);
});
}
void ShortcutItem::readConfig(KConfig *config)
{
const auto shortcuts = KGlobalAccel::self()->globalShortcut(m_actionCollection->componentName(), m_action->objectName());
m_savedShortcut = shortcuts.isEmpty() ? QKeySequence() : shortcuts.first();
m_action->setShortcut(m_savedShortcut);
}
void ShortcutItem::writeConfig(KConfig *config)
{
m_savedShortcut = m_action->shortcut();
KGlobalAccel::self()->setShortcut(m_action, {m_action->shortcut()}, KGlobalAccel::NoAutoloading);
}
void ShortcutItem::readDefault(KConfig *config)
{
}
void ShortcutItem::setDefault()
{
m_action->setShortcut(m_actionCollection->defaultShortcut(m_action));
}
void ShortcutItem::swapDefault()
{
QKeySequence previousShortcut = m_action->shortcut();
m_action->setShortcut(m_actionCollection->defaultShortcut(m_action));
m_actionCollection->setDefaultShortcut(m_action, previousShortcut);
}
bool ShortcutItem::isEqual(const QVariant &p) const
{
if (!p.canConvert<QKeySequence>()) {
return false;
}
return m_action->shortcut() == p.value<QKeySequence>();
}
QVariant ShortcutItem::property() const
{
return QVariant::fromValue<QKeySequence>(m_action->shortcut());
}
void ShortcutItem::setProperty(const QVariant &p)
{
m_action->setShortcut(p.value<QKeySequence>());
}
namespace KWin
{
namespace TabBox
{
ShortcutSettings::ShortcutSettings(QObject *parent)
: KConfigSkeleton(nullptr, parent)
, m_actionCollection(new KActionCollection(this, QStringLiteral("kwin")))
{
m_actionCollection->setConfigGroup("Navigation");
m_actionCollection->setConfigGlobal(true);
auto addShortcut = [this](const KLocalizedString &name, const QKeySequence &sequence = QKeySequence()) {
const QString untranslatedName = QString::fromUtf8(name.untranslatedText());
QAction *action = m_actionCollection->addAction(untranslatedName);
action->setObjectName(untranslatedName);
action->setProperty("isConfigurationAction", true);
action->setText(name.toString());
m_actionCollection->setDefaultShortcut(action, sequence);
addItem(new ShortcutItem(action, m_actionCollection));
};
// TabboxType::Main
addShortcut(ki18nd("kwin", "Walk Through Windows"), Qt::ALT | Qt::Key_Tab);
addShortcut(ki18nd("kwin", "Walk Through Windows (Reverse)"), Qt::ALT | Qt::SHIFT | Qt::Key_Tab);
addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application"), Qt::ALT | Qt::Key_QuoteLeft);
addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application (Reverse)"), Qt::ALT | Qt::Key_AsciiTilde);
// TabboxType::Alternative
addShortcut(ki18nd("kwin", "Walk Through Windows Alternative"));
addShortcut(ki18nd("kwin", "Walk Through Windows Alternative (Reverse)"));
addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application Alternative"));
addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application Alternative (Reverse)"));
}
KActionCollection *ShortcutSettings::actionCollection() const
{
return m_actionCollection;
}
QKeySequence ShortcutSettings::shortcut(const QString &name) const
{
QAction *action = m_actionCollection->action(name);
Q_ASSERT(action);
return action->shortcut();
}
void ShortcutSettings::setShortcut(const QString &name, const QKeySequence &seq)
{
QAction *action = m_actionCollection->action(name);
Q_ASSERT(action);
action->setShortcut(seq);
}
bool ShortcutSettings::isDefault(const QString &name) const
{
QAction *action = m_actionCollection->action(name);
Q_ASSERT(action);
return action->shortcut() == m_actionCollection->defaultShortcut(action);
}
} // namespace TabBox
} // namespace KWin
@@ -0,0 +1,40 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QKeySequence>
#include <KConfigSkeleton>
class KActionCollection;
namespace KWin
{
namespace TabBox
{
class ShortcutSettings : public KConfigSkeleton
{
public:
explicit ShortcutSettings(QObject *parent);
KActionCollection *actionCollection() const;
QKeySequence shortcut(const QString &name) const;
void setShortcut(const QString &name, const QKeySequence &seq);
bool isDefault(const QString &name) const;
private:
KActionCollection *m_actionCollection = nullptr;
};
} // namespace TabBox
} // namespace KWin
@@ -0,0 +1,113 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2011, 2014 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "thumbnailitem.h"
// Qt
#include <QDebug>
#include <QQuickWindow>
#include <QSGImageNode>
#include <QStandardPaths>
namespace KWin
{
WindowThumbnailItem::WindowThumbnailItem(QQuickItem *parent)
: QQuickItem(parent)
, m_wId(0)
, m_image()
, m_sourceSize(QSize())
{
setFlag(ItemHasContents);
}
WindowThumbnailItem::~WindowThumbnailItem()
{
}
void WindowThumbnailItem::setWId(qulonglong wId)
{
m_wId = wId;
Q_EMIT wIdChanged(wId);
findImage();
}
void WindowThumbnailItem::findImage()
{
QString imagePath;
switch (m_wId) {
case Konqueror:
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/falkon.png");
break;
case Systemsettings:
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/systemsettings.png");
break;
case KMail:
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/kmail.png");
break;
case Dolphin:
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/dolphin.png");
break;
case Desktop:
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "wallpapers/Next/contents/images/1280x800.png");
if (imagePath.isNull()) {
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/desktop.png");
}
break;
default:
// ignore
break;
}
if (imagePath.isNull()) {
m_image = QImage();
} else {
m_image = QImage(imagePath);
}
setImplicitSize(m_image.width(), m_image.height());
}
QSGNode *WindowThumbnailItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
{
auto *node = static_cast<QSGImageNode *>(oldNode);
if (!node) {
node = window()->createImageNode();
node->setOwnsTexture(true);
qsgnode_set_description(node, QStringLiteral("windowthumbnail"));
node->setFiltering(QSGTexture::Linear);
}
node->setTexture(window()->createTextureFromImage(m_image));
const QSize size(m_image.size().scaled(boundingRect().size().toSize(), Qt::KeepAspectRatio));
const qreal x = boundingRect().x() + (boundingRect().width() - size.width()) / 2;
const qreal y = boundingRect().y() + (boundingRect().height() - size.height()) / 2;
node->setRect(QRectF(QPointF(x, y), size));
return node;
}
QSize WindowThumbnailItem::sourceSize() const
{
return m_sourceSize;
}
void WindowThumbnailItem::setSourceSize(const QSize &size)
{
if (m_sourceSize == size) {
return;
}
m_sourceSize = size;
update();
Q_EMIT sourceSizeChanged();
}
} // namespace KWin
#include "moc_thumbnailitem.cpp"
@@ -0,0 +1,54 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2011, 2014 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QImage>
#include <QQuickItem>
namespace KWin
{
class WindowThumbnailItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(qulonglong wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged)
public:
explicit WindowThumbnailItem(QQuickItem *parent = nullptr);
~WindowThumbnailItem() override;
qulonglong wId() const
{
return m_wId;
}
QSize sourceSize() const;
void setWId(qulonglong wId);
void setSourceSize(const QSize &size);
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override;
enum Thumbnail {
Konqueror = 1,
KMail,
Systemsettings,
Dolphin,
Desktop,
};
Q_SIGNALS:
void wIdChanged(qulonglong wid);
void sourceSizeChanged();
private:
void findImage();
qulonglong m_wId;
QImage m_image;
QSize m_sourceSize;
};
} // KWin
Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB