feat: bury offline mode, ship antergos-layan-theme
remember when i thought an offline installer was a good idea? a pre-built squashfs that still needed internet to install DEs? "offline" in name only. it was a lie. a beautiful, naive lie. so i killed it. ripped out the mode picker, the connectivity check, the whole AskMode() circus. calamares-next now just shows a notice saying "yeah that wasnt actually offline" and launches directly into online mode. no more pretending. also fixed the QML nav button because having a greyed out "Next" on the last page is terrible UX. now it says "Done" and quits. youre welcome. and since we nuked the offline mode, might as well make the online mode look fucking spectacular. enter antergos-layan-theme: - kvantum theme because your apps deserve better than qt dreck - sddm theme (AntergosDark-Layan) for a sexy login screen - every plasma plasmoid from the rice (panel colorizer, netspeed, shutdown switch, applets, separators, music toolbar, the works) - yakuake arc-dark skin - antergos logos in /usr/share/logos and /usr/share/pixmaps - konsole profile, desktop appletsrc, all that jazz - kde_settings.conf now points to AntergosDark-Layan sddm theme also replaced the old antergos-grub-theme with the Layan grub theme because the old one was a git-sourced abomination. 75 distro icons, terminal box, selection widgets, antergos wallpaper. ships to /usr/share/grub/themes/antergos/ so calamares finds it. oh and a dozen audit fixes: - kscreenlockerrc wallpaper path fixed - kdialogrc no longer says some other distro - 7 stale knsregistry files deleted (dev machine was leaking) - systemd-inhibit guarded with command -v (dinit doesnt have it) - plasma restart uses killall not systemctl --user - "XeroLinux Toolkit" -> "Antergos Toolkit" in appletsrc - KDE_SESSION_VERSION=5 -> =6 (its 2026) - mirrorlist script says Artix not Arch - SDDM Messages.sh removed from build artifacts
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
// Cannot package without this file due to a bug in kpackagetool6
|
||||
// This file is empty on purpose, the implementation is done in the ui/main.qml file instead
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
<?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=""/>
|
||||
<group name="">
|
||||
<entry name="defaultTiler" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="centerInTileMode" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="rememberTiler" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="restoreSize" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="allowTransient" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="allowModal" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="tilerVisibility" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="revealMargin" type="Int">
|
||||
<default>200</default>
|
||||
</entry>
|
||||
<entry name="displayAs" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="windowVisibility" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="theme" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="tileMargin" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="screenMargin" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="defaultInput" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="showOverlayTextHint" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="overlayLayout" type="String">
|
||||
<default>4x2</default>
|
||||
</entry>
|
||||
<entry name="overlayScreenEdgeMargin" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="overlayPollingRate" type="Int">
|
||||
<default>100</default>
|
||||
</entry>
|
||||
<entry name="rememberAllLayouts" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="showTargetTileHint" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="showTextHint" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="gridTilerOpacity" type="Int">
|
||||
<default>100</default>
|
||||
<min>0</min>
|
||||
<max>100</max>
|
||||
</entry>
|
||||
<entry name="popupGridAt" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="horizontalAlignment" type="Int">
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="verticalAlignment" type="Int">
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="gridColumns" type="Int">
|
||||
<default>3</default>
|
||||
</entry>
|
||||
<entry name="gridAllColumns" type="Int">
|
||||
<default>6</default>
|
||||
</entry>
|
||||
<entry name="gridSpacing" type="Int">
|
||||
<default>10</default>
|
||||
</entry>
|
||||
<entry name="gridWidth" type="Int">
|
||||
<default>130</default>
|
||||
</entry>
|
||||
<entry name="gridHeight" type="Int">
|
||||
<default>70</default>
|
||||
</entry>
|
||||
<entry name="popupGridPollingRate" type="Int">
|
||||
<default>100</default>
|
||||
</entry>
|
||||
<entry name="virtualDesktopVisibility" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="virtualDesktopDropAction" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="virtualDesktopHoverTime" type="Int">
|
||||
<default>500</default>
|
||||
</entry>
|
||||
<entry name="moveBackOnDrop" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="moveBackOnTile" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="showAddVirtualDesktopButton" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="autoRemoveEmptyVirtualDesktops" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="popupLayout" type="String">
|
||||
<default>1x1
|
||||
2x1
|
||||
3x1
|
||||
SPECIAL_SPLIT_HORIZONTAL
|
||||
0,0,75,100+25,0,75,100+25,0,50,100
|
||||
4x1
|
||||
2x2
|
||||
SPECIAL_FILL
|
||||
4x2
|
||||
SPECIAL_AUTO_TILER_1
|
||||
SPECIAL_AUTO_TILER_2
|
||||
SPECIAL_AUTO_TILER_3</default>
|
||||
</entry>
|
||||
<entry name="allPopupLayouts" type="String">
|
||||
<default>SPECIAL_FILL
|
||||
SPECIAL_SPLIT_VERTICAL
|
||||
SPECIAL_SPLIT_HORIZONTAL
|
||||
SPECIAL_MAXIMIZE
|
||||
SPECIAL_MINIMIZE
|
||||
SPECIAL_FULLSCREEN
|
||||
0,0,50,100+50,0,50,50+50,50,50,50
|
||||
0,0,50,50+0,50,50,50+50,0,50,100
|
||||
0,0,25,50+0,50,25,50+25,0,50,100+75,0,25,50+75,50,25,50
|
||||
0,0,25,50+0,50,25,50+25,0,50,50+25,50,50,50+75,0,25,50+75,50,25,50
|
||||
SPECIAL_KEEP_ABOVE
|
||||
SPECIAL_KEEP_BELOW
|
||||
0,0,50,100+50,0,25,50+50,50,25,50+75,0,25,50+75,50,25,50
|
||||
0,0,25,50+0,50,25,50+25,0,25,50+25,50,25,50+50,0,50,100
|
||||
0,0,50,50+0,50,50,50+50,0,25,50+50,50,25,50+75,0,25,50+75,50,25,50
|
||||
0,0,25,50+0,50,25,50+25,0,25,50+25,50,25,50+50,0,50,50+50,50,50,50
|
||||
SPECIAL_NO_TITLEBAR_AND_FRAME
|
||||
SPECIAL_CLOSE
|
||||
1x1
|
||||
2x1
|
||||
3x1
|
||||
4x1
|
||||
5x1
|
||||
6x1
|
||||
1x2
|
||||
1x3
|
||||
1x4
|
||||
1x5
|
||||
0,0,75,100+25,0,75,100+25,0,50,100
|
||||
0,0,75,50+25,0,75,50+25,0,50,50+0,50,75,50+25,50,75,50+25,50,50,50
|
||||
2x2
|
||||
3x2
|
||||
4x2
|
||||
5x2
|
||||
0,0,67,100+33,0,67,100+17,0,66,100
|
||||
0,0,67,50+33,0,67,50+17,0,66,50+0,50,67,50+33,50,67,50+17,50,66,50
|
||||
2x3
|
||||
3x3
|
||||
4x3
|
||||
5x3
|
||||
1x1+17,0,66,100+33,0,34,100
|
||||
1x2+17,0,66,50+33,0,34,50+17,50,66,50+33,50,34,50
|
||||
11,25,26,50+37,25,26,50+63,25,26,50
|
||||
11,0,26,100+37,0,26,100+63,0,26,100
|
||||
11,0,26,50+37,0,26,50+63,0,26,50 + 11,50,26,50+37,50,26,50+63,50,26,50
|
||||
11,0,26,100+37,0,26,100+63,0,26,100 + 11,12,26,76+37,12,26,76+63,12,26,76 + 11,25,26,50+37,25,26,50+63,25,26,50
|
||||
1x1+12,0,76,100+25,0,50,100+37,0,26,100
|
||||
1x2+12,0,76,50+25,0,50,50+37,0,26,50+12,50,76,50+25,50,50,50+37,50,26,50
|
||||
0,25,37,50+37,25,26,50+63,25,37,50
|
||||
0,0,37,100+37,0,26,100+63,0,37,100
|
||||
0,0,37,50+37,0,26,50+63,0,37,50 + 0,50,37,50+37,50,26,50+63,50,37,50
|
||||
0,0,37,100+37,0,26,100+63,0,37,100 + 0,12,37,76+37,12,26,76+63,12,37,76 + 0,25,37,50+37,25,26,50+63,25,37,50
|
||||
1x1+17,17,66,66+33,33,34,34
|
||||
1x1+12,12,76,76+25,25,50,50+37,37,26,26
|
||||
0,0,25,100+75,0,25,100+25,0,50,100
|
||||
0,0,25,67+75,0,25,67+25,0,50,67+0,67,25,33+75,67,25,33+25,67,50,33
|
||||
0,0,25,33+75,0,25,33+25,0,50,33+0,33,25,67+75,33,25,67+25,33,50,67
|
||||
0,0,25,67+75,0,25,67+25,0,50,67+0,33,25,67+75,33,25,67+25,33,50,67
|
||||
0,0,33,67+33,0,34,67+67,0,33,67+0,67,33,33+33,67,34,33+67,67,33,33
|
||||
0,0,33,33+33,0,34,33+67,0,33,33+0,33,33,67+33,33,34,67+67,33,33,67
|
||||
0,0,67,100+67,0,33,100
|
||||
0,0,33,100+33,0,67,100
|
||||
0,0,67,100+67,0,33,50+67,50,33,50
|
||||
0,0,33,50+0,50,33,50+33,0,67,100
|
||||
0,0,67,50+67,0,33,50+0,50,67,50+67,50,33,50
|
||||
0,0,33,50+33,0,67,50+0,50,33,50+33,50,67,50
|
||||
SPECIAL_AUTO_TILER_TOGGLE
|
||||
SPECIAL_AUTO_TILER_1
|
||||
SPECIAL_AUTO_TILER_2
|
||||
SPECIAL_AUTO_TILER_3</default>
|
||||
</entry>
|
||||
<entry name="shortcutChangeMode" type="String">
|
||||
<default>Meta+Ctrl+Space</default>
|
||||
</entry>
|
||||
<entry name="shortcutShowAllSpan" type="String">
|
||||
<default>Ctrl+Space</default>
|
||||
</entry>
|
||||
<entry name="shortcutVisibility" type="String">
|
||||
<default>Meta+Space</default>
|
||||
</entry>
|
||||
<entry name="shortcutInputType" type="String">
|
||||
<default>Ctrl+Alt+I</default>
|
||||
</entry>
|
||||
<entry name="shortcutCenterInTile" type="String">
|
||||
<default>Meta+Ctrl+C</default>
|
||||
</entry>
|
||||
<entry name="shortcutMoveOnDrop" type="String">
|
||||
<default>Meta+Ctrl+V</default>
|
||||
</entry>
|
||||
<entry name="shortcutToggleTilingSuggestions" type="String">
|
||||
<default>Meta+Ctrl+S</default>
|
||||
</entry>
|
||||
<entry name="hintChangeMode" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="hintShowAllSpan" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="hintVisibility" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="hintInputType" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="hintCenterInTile" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="hintMoveOnDrop" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="hintToggleTilingSuggestions" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="showHintHint" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="debugLogs" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="showPositionHint" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="positionHintFormat" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="showSizeHint" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="sizeHintFormat" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileNewWindows" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="autoTilerEdgeScroll" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="autoTileMinimizedMaximized" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="autoTileRestoreSize" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="autoTileRestoreSizeAndPosition" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="autoTileToggleBehavior" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileIds" type="String">
|
||||
<default></default>
|
||||
</entry>
|
||||
<entry name="autoTileBlacklist" type="String">
|
||||
<default>krunner,kded,polkit,plasmashell,yakuake,spectacle,org.kde.spectacle,kded5,xwaylandvideobridge,ksplashqml,org.kde.plasmashell,org.kde.polkit-kde-authentication-agent-1,org.kde.kruler,kruler,kwin_wayland,kwin,ksmserver-logout-greeter,ksmserver</default>
|
||||
</entry>
|
||||
<entry name="autoTileWindowAction" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileWindowIndex" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileFocusAction" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileFocusIndex" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileMinimizedFocusAction" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileMinimizedFocusIndex" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileDragSwapAction" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="autoTileLayer" type="Int">
|
||||
<default>2</default>
|
||||
</entry>
|
||||
<entry name="maxAutoTileDelay" type="Int">
|
||||
<default>5</default>
|
||||
</entry>
|
||||
<entry name="maxAutoTileDelaySessionStart" type="Int">
|
||||
<default>10</default>
|
||||
</entry>
|
||||
<entry name="autoTilerMode1" type="Int">
|
||||
<default>8</default>
|
||||
</entry>
|
||||
<entry name="autoTilerMode2" type="Int">
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="autoTilerMode3" type="Int">
|
||||
<default>12</default>
|
||||
</entry>
|
||||
<entry name="autoTilerCustom1" type="String">
|
||||
<default>0:0,0,100,100
|
||||
0:0,0,50,100+1:50,0,50,100
|
||||
0:0,0,50,100+1:50,0,50,50+2:50,50,50,50
|
||||
0:0,0,50,50+3:0,50,50,50+1:50,0,50,50+2:50,50,50,50</default>
|
||||
</entry>
|
||||
<entry name="autoTilerCustom2" type="String">
|
||||
<default>{"carousel":true}
|
||||
0:0,0,100,100</default>
|
||||
</entry>
|
||||
<entry name="autoTilerCustom3" type="String">
|
||||
<default>0:0,0,67,100
|
||||
0:0,0,67,100+1:67,0,33,100
|
||||
0:0,0,67,100+1:67,0,33,50+2:67,50,33,50</default>
|
||||
</entry>
|
||||
<entry name="autoTilerCarousel1" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="autoTilerCarousel2" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="autoTilerCarousel3" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="suggestionsVisibility" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="suggestionsMode" type="Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="suggestOtherScreens" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="suggestOtherDesktops" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="suggestOtherActivities" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="suggestAutoTiled" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="suggestMinimized" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
||||
+1763
File diff suppressed because it is too large
Load Diff
+239
@@ -0,0 +1,239 @@
|
||||
import QtQuick
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
|
||||
property bool lightTheme: {
|
||||
return Kirigami.ColorUtils.brightnessForColor(Kirigami.Theme.backgroundColor) === Kirigami.ColorUtils.Light;
|
||||
}
|
||||
|
||||
property var backgroundColor: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "#161925";
|
||||
case 2:
|
||||
return "#110B00";
|
||||
case 3:
|
||||
return "#FFFFFF";
|
||||
case 4:
|
||||
return "#110000";
|
||||
case 5:
|
||||
return "#020900";
|
||||
case 6:
|
||||
return "#0A0010";
|
||||
case 7:
|
||||
return "#001100";
|
||||
case 8:
|
||||
return "#111100";
|
||||
case 9:
|
||||
return "#000710";
|
||||
default:
|
||||
return Kirigami.Theme.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
property var borderColor: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "#666666";
|
||||
case 2:
|
||||
return "#7F4F00";
|
||||
case 3:
|
||||
return "#777777";
|
||||
case 4:
|
||||
return "#780000";
|
||||
case 5:
|
||||
return "#587C00";
|
||||
case 6:
|
||||
return "#4A0076";
|
||||
case 7:
|
||||
return "#225522";
|
||||
case 8:
|
||||
return "#555500";
|
||||
case 9:
|
||||
return "#004093";
|
||||
default:
|
||||
if (lightTheme) {
|
||||
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, "black", 0.2);
|
||||
} else {
|
||||
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, "white", 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property var textColor: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "white";
|
||||
case 2:
|
||||
return "white";
|
||||
case 3:
|
||||
return "black";
|
||||
case 4:
|
||||
return "white";
|
||||
case 5:
|
||||
return "white";
|
||||
case 6:
|
||||
return "white";
|
||||
case 7:
|
||||
return "white";
|
||||
case 8:
|
||||
return "white";
|
||||
case 9:
|
||||
return "white";
|
||||
default:
|
||||
return lightTheme ? "black" : "white";
|
||||
}
|
||||
}
|
||||
|
||||
property var overlayTextColor: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "white";
|
||||
case 2:
|
||||
return "white";
|
||||
case 3:
|
||||
return "black";
|
||||
case 4:
|
||||
return "black";
|
||||
case 5:
|
||||
return "black";
|
||||
case 6:
|
||||
return "white";
|
||||
case 7:
|
||||
return "black";
|
||||
case 8:
|
||||
return "black";
|
||||
case 9:
|
||||
return "white";
|
||||
default:
|
||||
return lightTheme ? "black" : "white";
|
||||
}
|
||||
}
|
||||
|
||||
property var hintBackgroundColor: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "#590099FF";
|
||||
case 2:
|
||||
return "#59FF9F00";
|
||||
case 3:
|
||||
return "#59FF0000";
|
||||
case 4:
|
||||
return "#59FF0000";
|
||||
case 5:
|
||||
return "#59B5FF00";
|
||||
case 6:
|
||||
return "#599F00FF";
|
||||
case 7:
|
||||
return "#5900FF00";
|
||||
case 8:
|
||||
return "#59FFFF00";
|
||||
case 9:
|
||||
return "#590067FF";
|
||||
default:
|
||||
return Kirigami.ColorUtils.tintWithAlpha("transparent", Kirigami.Theme.highlightColor, 0.35);
|
||||
}
|
||||
}
|
||||
|
||||
property var tileBorderColor: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "#0099FF";
|
||||
case 2:
|
||||
return "#FF9F00";
|
||||
case 3:
|
||||
return "#FF0000";
|
||||
case 4:
|
||||
return "#FF0000";
|
||||
case 5:
|
||||
return "#B5FF00";
|
||||
case 6:
|
||||
return "#9F00FF";
|
||||
case 7:
|
||||
return "#00FF00";
|
||||
case 8:
|
||||
return "#FFFF00";
|
||||
case 9:
|
||||
return "#0067FF";
|
||||
default:
|
||||
return Kirigami.Theme.highlightColor;
|
||||
}
|
||||
}
|
||||
|
||||
property var tileBackgroundColor: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "#0C0099FF";
|
||||
case 2:
|
||||
return "#0CFF9F00";
|
||||
case 3:
|
||||
return "#3CFF0000";
|
||||
case 4:
|
||||
return "#3CFF0000";
|
||||
case 5:
|
||||
return "#3CB5FF00";
|
||||
case 6:
|
||||
return "#3C9F00FF";
|
||||
case 7:
|
||||
return "#3C00FF00";
|
||||
case 8:
|
||||
return "#3CFFFF00";
|
||||
case 9:
|
||||
return "#3C0067FF";
|
||||
default:
|
||||
return Kirigami.ColorUtils.tintWithAlpha("transparent", Kirigami.Theme.highlightColor, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
property var tileBackgroundColorIntense: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "#3C0099FF";
|
||||
case 2:
|
||||
return "#3CFF9F00";
|
||||
case 3:
|
||||
return "#3CFF0000";
|
||||
case 4:
|
||||
return "#3CFF0000";
|
||||
case 5:
|
||||
return "#3CB5FF00";
|
||||
case 6:
|
||||
return "#3C9F00FF";
|
||||
case 7:
|
||||
return "#3C00FF00";
|
||||
case 8:
|
||||
return "#3CFFFF00";
|
||||
case 9:
|
||||
return "#3C0067FF";
|
||||
default:
|
||||
return Kirigami.ColorUtils.tintWithAlpha("transparent", Kirigami.Theme.highlightColor, 0.23);
|
||||
}
|
||||
}
|
||||
|
||||
property var tileBackgroundColorActive: {
|
||||
switch (config.theme) {
|
||||
case 1:
|
||||
return "#BE0099FF";
|
||||
case 2:
|
||||
return "#BEFF9F00";
|
||||
case 3:
|
||||
return "#BEFF0000";
|
||||
case 4:
|
||||
return "#BEFF0000";
|
||||
case 5:
|
||||
return "#BEB5FF00";
|
||||
case 6:
|
||||
return "#BE9F00FF";
|
||||
case 7:
|
||||
return "#BE00FF00";
|
||||
case 8:
|
||||
return "#BEFFFF00";
|
||||
case 9:
|
||||
return "#BE0067FF";
|
||||
default:
|
||||
return Kirigami.ColorUtils.tintWithAlpha("transparent", Kirigami.Theme.highlightColor, 0.75);
|
||||
}
|
||||
}
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kwin
|
||||
import org.kde.kirigami as Kirigami
|
||||
// import QtWebView
|
||||
|
||||
ApplicationWindow {
|
||||
property var overrides: {}
|
||||
property var currentOverrides: {}
|
||||
property var currentApplications: []
|
||||
property var currentWindows: []
|
||||
property var defaultConfig: {}
|
||||
property var currentApplicationIndex: -1
|
||||
property var currentWindowIndex: -1
|
||||
// property var isX11: Qt.platform.pluginName == 'xcb'
|
||||
property var mouseStartX
|
||||
property var mouseStartY
|
||||
property var windowStartX
|
||||
property var windowStartY
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
|
||||
property var lightTheme: {
|
||||
return Kirigami.ColorUtils.brightnessForColor(Kirigami.Theme.backgroundColor) === Kirigami.ColorUtils.Light;
|
||||
}
|
||||
|
||||
property var headerColor: {
|
||||
if (lightTheme) {
|
||||
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, "white", 0.4);
|
||||
} else {
|
||||
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, "black", 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
property var headerBorderColor: {
|
||||
if (lightTheme) {
|
||||
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, "black", 0.2);
|
||||
} else {
|
||||
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, "white", 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
id: mainMenuRoot
|
||||
width: 1000
|
||||
height: 734
|
||||
title: "Mouse Tiler Configuration"
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
flags: Qt.FramelessWindowHint | Qt.Window | Qt.BypassWindowManagerHint
|
||||
// flags: ixX11 ? Qt.X11BypassWindowManagerHint : flags
|
||||
|
||||
// x: isX11 ? Workspace.virtualScreenSize.width / 2 - width / 2 : x
|
||||
// y: isX11 ? Workspace.virtualScreenSize.height / 2 - height / 2 : y
|
||||
x: Workspace.virtualScreenSize.width / 2 - width / 2
|
||||
y: Workspace.virtualScreenSize.height / 2 - height / 2
|
||||
|
||||
function initMainMenu() {
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: headerColor
|
||||
height: 34
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
border.color: headerBorderColor
|
||||
border.width: 1
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
onPressed: {
|
||||
mouseStartX = Workspace.cursorPos.x;
|
||||
mouseStartY = Workspace.cursorPos.y;
|
||||
windowStartX = mainMenuRoot.x;
|
||||
windowStartY = mainMenuRoot.y;
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
mainMenuRoot.x = windowStartX + (Workspace.cursorPos.x - mouseStartX);
|
||||
mainMenuRoot.y = windowStartY + (Workspace.cursorPos.y - mouseStartY);
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
mainMenuRoot.x = windowStartX + (Workspace.cursorPos.x - mouseStartX);
|
||||
mainMenuRoot.y = windowStartY + (Workspace.cursorPos.y - mouseStartY);
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Mouse Tiler Configuration"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "X"
|
||||
flat: true
|
||||
|
||||
width: 26
|
||||
height: 26
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 4
|
||||
|
||||
onClicked: root.closeMainMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
id: mainGroupBox
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 35
|
||||
|
||||
// WebView {
|
||||
// id: webView
|
||||
// anchors.fill: parent
|
||||
// url: "https://rxweb.epizy.com/mousetiler/editor.html"
|
||||
// }
|
||||
|
||||
ColumnLayout {
|
||||
id: mainChoice
|
||||
visible: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
GroupBox {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "This was meant to be the UI designer. However it is a lot of work to implement it, probaly at least 1-2 weeks full time. Sadly I got rent to pay and a 3 year old son to feed and based on my previous project Remember Window Positions, I will not be able to feed us from my contributions to Linux. (After over 3 months full time work I earned $100 total which I apreciate but it's not possible to survive on). I might implement it in the future if the situation changes."
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
// Label {
|
||||
// Layout.fillWidth: true
|
||||
// text: "Not implemented yet"
|
||||
// wrapMode: Text.WordWrap
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// GroupBox {
|
||||
// spacing: 5
|
||||
// Layout.fillWidth: true
|
||||
|
||||
// ColumnLayout {
|
||||
// anchors.fill: parent
|
||||
|
||||
// Label {
|
||||
// Layout.fillWidth: true
|
||||
// horizontalAlignment: Text.AlignHCenter
|
||||
// text: "."
|
||||
// wrapMode: Text.WordWrap
|
||||
// }
|
||||
|
||||
// Button {
|
||||
// id: selectWindowButton
|
||||
// text: "Select Application/Window"
|
||||
// Layout.fillWidth: true
|
||||
|
||||
// onClicked: selectWindow()
|
||||
// }
|
||||
|
||||
// Button {
|
||||
// text: "Edit Saved Applications and Windows"
|
||||
// Layout.fillWidth: true
|
||||
|
||||
// onClicked: editSavedAppOrWindow()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
import QtQuick
|
||||
import org.kde.kwin
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
|
||||
// Window {
|
||||
PlasmaCore.Dialog {
|
||||
id: overlayTiler
|
||||
|
||||
property var activeScreen: null
|
||||
property var clientArea: ({width: 1, height: 1, x: 0, y: 0})
|
||||
property var tilePadding: 2
|
||||
property int activeIndex: -1
|
||||
property int spanFromIndex: -1
|
||||
property int minSpanX: -1
|
||||
property int minSpanY: -1
|
||||
property int maxSpanX: -1
|
||||
property int maxSpanY: -1
|
||||
property var convertedOverlay: ([])
|
||||
|
||||
// Workaround for plasma 6.6 and earlier - needed by Window and Plasma Dialog - replaced by Qt.WindowTransparentForInput in Plasma 6.7
|
||||
property bool outputOnly: true
|
||||
|
||||
width: clientArea.width - root.config.overlayScreenEdgeMargin * 2
|
||||
height: clientArea.height - root.config.overlayScreenEdgeMargin * 2
|
||||
x: clientArea.x + root.config.overlayScreenEdgeMargin
|
||||
y: clientArea.y + root.config.overlayScreenEdgeMargin
|
||||
// flags: Qt.Popup | Qt.BypassWindowManagerHint | Qt.FramelessWindowHint
|
||||
// flags: Qt.Tool | Qt.BypassWindowManagerHint | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus
|
||||
flags: (root.config.displayAs == 0 ? 0 : Qt.Popup) | (Qt.BypassWindowManagerHint | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.WindowTransparentForInput)
|
||||
// color: "transparent" // Window
|
||||
visible: false
|
||||
backgroundHints: PlasmaCore.Types.NoBackground // PlasmaCore.Dialog
|
||||
// outputOnly: true // PlasmaCore.Dialog
|
||||
// type: PlasmaCore.Dialog.OnScreenDisplay
|
||||
location: PlasmaCore.Types.Desktop // PlasmaCore.Dialog
|
||||
|
||||
function reset() {
|
||||
activeScreen = null;
|
||||
spanFromIndex = -1;
|
||||
activeIndex = -1;
|
||||
updateSpan();
|
||||
}
|
||||
|
||||
function startAnimations() {
|
||||
overlayTiler.opacity = 0;
|
||||
showOverlayTilerAnimation.start();
|
||||
}
|
||||
|
||||
function updateScreen() {
|
||||
if (activeScreen != Workspace.activeScreen) {
|
||||
autoTiler.updateShouldShowScreenEdges();
|
||||
root.logE('updateScreen ' + Workspace.virtualScreenSize);
|
||||
reset();
|
||||
activeScreen = Workspace.activeScreen;
|
||||
clientArea = Workspace.clientArea(KWin.FullScreenArea, activeScreen, Workspace.currentDesktop);
|
||||
convertLayoutToScreen();
|
||||
}
|
||||
}
|
||||
|
||||
function convertLayoutToScreen() {
|
||||
let layout = root.config.overlay;
|
||||
let converted = [];
|
||||
for (let i = 0; i < layout.length; i++) {
|
||||
let tile = layout[i];
|
||||
let width = (tile.pxW == undefined ? tile.w / 100 * mainItem.width : tile.pxW);
|
||||
let height = (tile.pxH == undefined ? tile.h / 100 * mainItem.height : tile.pxH);
|
||||
converted.push({
|
||||
pxX: (tile.pxX == undefined ? tile.x / 100 * mainItem.width : tile.pxX) - (tile.aX == undefined ? 0 : tile.aX * width / 100),
|
||||
pxY: (tile.pxY == undefined ? tile.y / 100 * mainItem.height : tile.pxY) - (tile.aY == undefined ? 0 : tile.aY * height / 100),
|
||||
pxW: width,
|
||||
pxH: height
|
||||
});
|
||||
}
|
||||
convertedOverlay = converted;
|
||||
}
|
||||
|
||||
function toggleSpan() {
|
||||
if (spanFromIndex != activeIndex && spanFromIndex == -1) {
|
||||
spanFromIndex = activeIndex;
|
||||
updateSpan();
|
||||
} else if (spanFromIndex >= 0) {
|
||||
spanFromIndex = -1;
|
||||
updateSpan();
|
||||
}
|
||||
}
|
||||
|
||||
function updateSpan() {
|
||||
if (activeIndex == -1 || spanFromIndex == -1) {
|
||||
minSpanX = -1;
|
||||
minSpanY = -1;
|
||||
maxSpanX = -1;
|
||||
maxSpanY = -1;
|
||||
} else {
|
||||
let itemActive = tileRepeater.itemAt(activeIndex);
|
||||
let itemSpan = tileRepeater.itemAt(spanFromIndex);
|
||||
minSpanX = Math.min(itemActive.x, itemSpan.x);
|
||||
minSpanY = Math.min(itemActive.y, itemSpan.y);
|
||||
maxSpanX = Math.max(itemActive.x + itemActive.width, itemSpan.x + itemSpan.width);
|
||||
maxSpanY = Math.max(itemActive.y + itemActive.height, itemSpan.y + itemSpan.height);
|
||||
}
|
||||
root.log('Span activeIndex: ' + activeIndex + ' spanFromIndex: ' + spanFromIndex + ' minSpanX: ' + minSpanX + ' minSpanY: ' + minSpanY + ' maxSpanX: ' + maxSpanX + ' maxSpanY: ' + maxSpanY);
|
||||
}
|
||||
|
||||
function getGeometry() {
|
||||
if (activeIndex >= 0) {
|
||||
let x, y, width, height;
|
||||
if (spanFromIndex >= 0) {
|
||||
x = clientArea.x + minSpanX;
|
||||
y = clientArea.y + minSpanY;
|
||||
width = maxSpanX - minSpanX;
|
||||
height = maxSpanY - minSpanY;
|
||||
} else {
|
||||
let item = tileRepeater.itemAt(activeIndex);
|
||||
x = clientArea.x + item.x;
|
||||
y = clientArea.y + item.y;
|
||||
width = item.width;
|
||||
height = item.height;
|
||||
}
|
||||
if (root.centerInTile) {
|
||||
return {
|
||||
x: x + width / 2 - root.currentlyMovedWindow.width / 2,
|
||||
y: y + height / 2 - root.currentlyMovedWindow.height / 2,
|
||||
width: root.currentlyMovedWindow.width,
|
||||
height: root.currentlyMovedWindow.height
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getActiveVirtualDesktopIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: mainItem
|
||||
width: popupTiler.width
|
||||
height: popupTiler.height
|
||||
|
||||
SequentialAnimation {
|
||||
id: showOverlayTilerAnimation
|
||||
running: false
|
||||
|
||||
NumberAnimation {
|
||||
target: overlayTiler;
|
||||
property: "opacity";
|
||||
from: 0;
|
||||
to: 0;
|
||||
duration: 32;
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: overlayTiler;
|
||||
property: "opacity";
|
||||
from: 1;
|
||||
to: 1;
|
||||
duration: 1;
|
||||
}
|
||||
|
||||
onFinished: {
|
||||
root.updateWindowVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
Colors {
|
||||
id: colors
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: tileRepeater
|
||||
model: overlayTiler.convertedOverlay
|
||||
|
||||
Item {
|
||||
id: tile
|
||||
|
||||
property bool active: activeIndex == index
|
||||
property bool spanned: !active && Math.ceil(modelData.pxX) >= Math.floor(minSpanX) && Math.floor(modelData.pxX) + Math.floor(modelData.pxW) <= Math.ceil(maxSpanX) && Math.ceil(modelData.pxY) >= Math.floor(minSpanY) && Math.floor(modelData.pxY) + Math.floor(modelData.pxH) <= Math.ceil(maxSpanY)
|
||||
property bool spannedFrom: spanFromIndex == index
|
||||
|
||||
x: modelData.pxX
|
||||
y: modelData.pxY
|
||||
width: modelData.pxW
|
||||
height: modelData.pxH
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: tilePadding
|
||||
border.color: colors.tileBorderColor
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
radius: 12
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 12
|
||||
color: active || spanned ? colors.tileBackgroundColorActive : colors.tileBackgroundColor
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
color: colors.overlayTextColor
|
||||
textFormat: Text.StyledText
|
||||
text: {
|
||||
let defaultHint = "";
|
||||
let insertExtraBreak = false;
|
||||
|
||||
if (root.config.showHintHint) {
|
||||
defaultHint += (defaultHint.length > 0 ? "<br>" : "") + "Configure tiler visibility and these hints in settings.";
|
||||
insertExtraBreak = true;
|
||||
}
|
||||
if (root.config.hintShowAllSpan) {
|
||||
if (insertExtraBreak) {
|
||||
defaultHint += "<br>";
|
||||
insertExtraBreak = false;
|
||||
}
|
||||
defaultHint += (defaultHint.length > 0 ? "<br>" : "") + (spannedFrom ? "Stop spanning (<b>" + root.config.shortcutShowAllSpan + "</b>)" : "Span from this tile (<b>" + root.config.shortcutShowAllSpan + "</b>)");
|
||||
insertExtraBreak = true;
|
||||
}
|
||||
if (root.config.hintVisibility) {
|
||||
if (insertExtraBreak) {
|
||||
defaultHint += "<br>";
|
||||
insertExtraBreak = false;
|
||||
}
|
||||
defaultHint += (defaultHint.length > 0 ? "<br>" : "") + "Toggle visibility (<b>" + root.config.shortcutVisibility + "</b>)";
|
||||
}
|
||||
if (root.config.hintInputType) {
|
||||
if (insertExtraBreak) {
|
||||
defaultHint += "<br>";
|
||||
insertExtraBreak = false;
|
||||
}
|
||||
defaultHint += (defaultHint.length > 0 ? "<br>" : "") + "Input type: " + (root.useMouseCursor ? "Mouse" : "Window") + " (<b>" + root.config.shortcutInputType + "</b>)";
|
||||
}
|
||||
if (root.config.hintCenterInTile) {
|
||||
if (insertExtraBreak) {
|
||||
defaultHint += "<br>";
|
||||
insertExtraBreak = false;
|
||||
}
|
||||
defaultHint += (defaultHint.length > 0 ? "<br>" : "") + "Center in tile: " + (root.centerInTile ? "Enabled" : "Disabled") + " (<b>" + root.config.shortcutCenterInTile + "</b>)";
|
||||
}
|
||||
if (root.config.hintChangeMode) {
|
||||
insertExtraBreak = false;
|
||||
defaultHint += (defaultHint.length > 0 ? "<br><br>" : "") + "Switch mode (<b>" + root.config.shortcutChangeMode + "</b>)";
|
||||
}
|
||||
|
||||
if (root.centerInTile) {
|
||||
return (spannedFrom ? "<b>Center in spanned tiles</b><br><br>" : "<b>Center in this tile</b><br><br>") + defaultHint;
|
||||
} else {
|
||||
return defaultHint;
|
||||
}
|
||||
return defaultHint;
|
||||
}
|
||||
font.pixelSize: 16
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: root.config.showOverlayTextHint && (active && spanFromIndex == -1 || spannedFrom)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: popupWindowCursor
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.getCursorPosition().x - clientArea.x - 6
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: root.getCursorPosition().y - clientArea.y - 6
|
||||
width: 12
|
||||
height: 12
|
||||
border.color: colors.tileBorderColor
|
||||
border.width: 2
|
||||
color: colors.tileBackgroundColorActive
|
||||
radius: 6
|
||||
visible: !root.useMouseCursor
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 2
|
||||
height: 2
|
||||
color: colors.textColor
|
||||
radius: 1
|
||||
opacity: 0.8
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: root.config.overlayPollingRate
|
||||
repeat: true
|
||||
running: overlayTiler.visible
|
||||
onTriggered: {
|
||||
updateScreen();
|
||||
|
||||
let localCursorPos = Workspace.activeScreen.mapFromGlobal(root.getCursorPosition());
|
||||
let x = localCursorPos.x - root.config.overlayScreenEdgeMargin;
|
||||
let y = localCursorPos.y - root.config.overlayScreenEdgeMargin;
|
||||
let index = -1;
|
||||
|
||||
for (let i = 0; i < tileRepeater.count; i++) {
|
||||
let item = tileRepeater.itemAt(i);
|
||||
if (item.x <= x && item.x + item.width >= x && item.y <= y && item.y + item.height >= y) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index != activeIndex) {
|
||||
activeIndex = index;
|
||||
updateSpan();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+978
@@ -0,0 +1,978 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kwin
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
|
||||
// Window {
|
||||
PlasmaCore.Dialog {
|
||||
id: popupTiler
|
||||
|
||||
property var activeScreen: null
|
||||
property var clientArea: ({width: 1, height: 1, x: 0, y: 0})
|
||||
property int tilePadding: 2
|
||||
property int borderOffset: 2
|
||||
property int activeLayoutIndex: -1
|
||||
property int activeTileIndex: -1
|
||||
property int positionX: 0
|
||||
property int positionY: 0
|
||||
property bool showAll: false
|
||||
property bool lastShowAll: false
|
||||
property var hint: null
|
||||
property bool showPopupDropHint: false
|
||||
property bool hasValidPopupDropHint: false
|
||||
property var popupDropHintX: 0
|
||||
property var popupDropHintY: 0
|
||||
property var popupDropHintWidth: 0
|
||||
property var popupDropHintHeight: 0
|
||||
property bool popupDropHintIsCenterInTile: false
|
||||
property bool sizeEstablished: false
|
||||
property var revealBox: null
|
||||
property bool revealed: false
|
||||
property bool currentlyHovered: false
|
||||
property int activeVirtualDesktopIndex: -1
|
||||
property var activeVirtualDesktopHoverTime: -1
|
||||
property bool virtualDesktopVisibilityOverride: false
|
||||
// property bool shouldShowAutoTileScroll: false
|
||||
// property var scrollLeftTime: 0
|
||||
// property var scrollRightTime: 0
|
||||
|
||||
// Workaround for plasma 6.6 and earlier - needed by Window and Plasma Dialog - replaced by Qt.WindowTransparentForInput in Plasma 6.7
|
||||
property bool outputOnly: true
|
||||
|
||||
width: clientArea.width
|
||||
height: clientArea.height
|
||||
x: clientArea.x
|
||||
y: clientArea.y
|
||||
//flags: Qt.Popup | Qt.BypassWindowManagerHint | Qt.FramelessWindowHint
|
||||
// flags: Qt.Tool | Qt.BypassWindowManagerHint | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus
|
||||
flags: (root.config.displayAs == 0 ? 0 : Qt.Popup) | (Qt.BypassWindowManagerHint | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.WindowTransparentForInput)
|
||||
// color: "transparent" // Window
|
||||
visible: false
|
||||
backgroundHints: PlasmaCore.Types.NoBackground // PlasmaCore.Dialog
|
||||
// outputOnly: true // PlasmaCore.Dialog
|
||||
// type: PlasmaCore.Dialog.OnScreenDisplay
|
||||
location: PlasmaCore.Types.Desktop // PlasmaCore.Dialog
|
||||
|
||||
function reset() {
|
||||
activeScreen = null;
|
||||
activeLayoutIndex = -1;
|
||||
activeTileIndex = -1;
|
||||
hint = null;
|
||||
showPopupDropHint = false;
|
||||
updateHintContent();
|
||||
}
|
||||
|
||||
function resetShowAll() {
|
||||
showAll = false;
|
||||
lastShowAll = false;
|
||||
}
|
||||
|
||||
function startAnimations() {
|
||||
popupTiler.opacity = 0;
|
||||
showPopupTilerAnimation.start();
|
||||
}
|
||||
|
||||
function updateScreen(forceUpdate = false) {
|
||||
if (forceUpdate || activeScreen != Workspace.activeScreen) {
|
||||
root.logE('updateScreen ' + Workspace.virtualScreenSize);
|
||||
if (activeScreen != Workspace.activeScreen) {
|
||||
autoTiler.updateAutoTilersInPopupTiler();
|
||||
}
|
||||
autoTiler.updateShouldShowScreenEdges();
|
||||
// shouldShowAutoTileScroll = autoTiler.shouldShowAutoTileScroll();
|
||||
activeScreen = Workspace.activeScreen;
|
||||
clientArea = Workspace.clientArea(KWin.FullScreenArea, Workspace.activeScreen, Workspace.currentDesktop);
|
||||
|
||||
let localCursorPos = Workspace.activeScreen.mapFromGlobal(root.getCursorPosition());
|
||||
|
||||
let visibleHeight = virtualDesktopVisibilityOverride || root.config.virtualDesktopVisibility != 1 ? layouts.height : 0;
|
||||
|
||||
if (root.config.popupGridAt == 0) {
|
||||
switch (root.config.horizontalAlignment) {
|
||||
default:
|
||||
positionX = localCursorPos.x - root.config.gridWidth / 2 - root.config.gridSpacing;
|
||||
break;
|
||||
case 1:
|
||||
positionX = localCursorPos.x - layouts.width / 2;
|
||||
break;
|
||||
case 2:
|
||||
positionX = localCursorPos.x - layouts.width + root.config.gridWidth / 2 + root.config.gridSpacing;
|
||||
break;
|
||||
}
|
||||
|
||||
if (visibleHeight == 0) {
|
||||
positionY = localCursorPos.y;
|
||||
} else {
|
||||
switch (root.config.verticalAlignment) {
|
||||
default:
|
||||
positionY = localCursorPos.y - root.config.gridHeight / 2 - root.config.gridSpacing;
|
||||
break;
|
||||
case 1:
|
||||
positionY = localCursorPos.y - layouts.height / 2;
|
||||
break;
|
||||
case 2:
|
||||
positionY = localCursorPos.y - layouts.height + root.config.gridHeight / 2 + root.config.gridSpacing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (root.config.horizontalAlignment) {
|
||||
default:
|
||||
positionX = 0;
|
||||
break;
|
||||
case 1:
|
||||
positionX = clientArea.width / 2 - layouts.width / 2;
|
||||
break;
|
||||
case 2:
|
||||
positionX = clientArea.width - layouts.width;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (root.config.verticalAlignment) {
|
||||
default:
|
||||
positionY = 0;
|
||||
break;
|
||||
case 1:
|
||||
positionY = clientArea.height / 2 - visibleHeight / 2;
|
||||
break;
|
||||
case 2:
|
||||
positionY = clientArea.height - visibleHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// positionX = localCursorPos.x - layouts.width / 2;
|
||||
// positionY = localCursorPos.y - (layouts.height + popupHint.height + 2) / 2;
|
||||
|
||||
if (positionX < 0) {
|
||||
positionX = 0;
|
||||
} else if (positionX + layouts.width > popupTiler.width) {
|
||||
positionX = popupTiler.width - layouts.width;
|
||||
}
|
||||
|
||||
let totalHeight = visibleHeight;
|
||||
if (root.virtualDesktopVisibile) {
|
||||
if (totalHeight > 0) {
|
||||
totalHeight += 2;
|
||||
}
|
||||
totalHeight += virtualDesktop.height;
|
||||
}
|
||||
if (root.config.showTextHint) {
|
||||
totalHeight += popupHint.height + 2;
|
||||
}
|
||||
|
||||
if (positionY < 0) {
|
||||
positionY = 0;
|
||||
} else if (positionY + totalHeight > popupTiler.height) {
|
||||
positionY = popupTiler.height - totalHeight;
|
||||
}
|
||||
|
||||
if (root.config.tilerVisibility == 3) {
|
||||
let triggerLeft = Math.max(positionX - config.revealMargin, 0);
|
||||
let triggerRight = Math.min(positionX + layouts.width + config.revealMargin, popupTiler.width);
|
||||
let triggerTop = Math.max(positionY - config.revealMargin, 0);
|
||||
let triggerBottom = Math.min(positionY + totalHeight + config.revealMargin, popupTiler.height);
|
||||
let leftTop = Workspace.activeScreen.mapToGlobal(Qt.point(triggerLeft, triggerTop));
|
||||
let rightBottom = Workspace.activeScreen.mapToGlobal(Qt.point(triggerRight, triggerBottom));
|
||||
revealBox = { left: leftTop.x, right: rightBottom.x, top: leftTop.y, bottom: rightBottom.y };
|
||||
updateRevealed(true);
|
||||
} else {
|
||||
revealBox = null;
|
||||
updateRevealed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getGeometry() {
|
||||
if (activeLayoutIndex >= 0 && activeTileIndex >= 0) {
|
||||
if (root.centerInTile && hasValidPopupDropHint) {
|
||||
return {
|
||||
x: clientArea.x + popupDropHintX,
|
||||
y: clientArea.y + popupDropHintY,
|
||||
width: popupDropHintWidth,
|
||||
height: popupDropHintHeight
|
||||
};
|
||||
} else if (layoutRepeater.model[activeLayoutIndex].special) {
|
||||
return {
|
||||
special: layoutRepeater.model[activeLayoutIndex].special,
|
||||
specialMode: activeTileIndex
|
||||
};
|
||||
} else if (!root.centerInTile) {
|
||||
return {
|
||||
x: clientArea.x + popupDropHintX,
|
||||
y: clientArea.y + popupDropHintY,
|
||||
width: popupDropHintWidth,
|
||||
height: popupDropHintHeight,
|
||||
defaultLayouts: !showAll,
|
||||
layoutIndex: activeLayoutIndex,
|
||||
tileIndex: activeTileIndex
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getActiveVirtualDesktopIndex() {
|
||||
return activeVirtualDesktopIndex;
|
||||
}
|
||||
|
||||
function resetVirtualDesktopOverride() {
|
||||
virtualDesktopVisibilityOverride = false;
|
||||
}
|
||||
|
||||
function toggleShowAll() {
|
||||
reset();
|
||||
if (root.config.virtualDesktopVisibility == 1 && !virtualDesktopVisibilityOverride) {
|
||||
virtualDesktopVisibilityOverride = true;
|
||||
} else {
|
||||
showAll = !showAll;
|
||||
updateHintContent();
|
||||
}
|
||||
}
|
||||
|
||||
function updateAndShowPopupDropHint() {
|
||||
let shouldShowPopupDropHint = false;
|
||||
let special = layoutRepeater.model[activeLayoutIndex].special;
|
||||
let geometry = null;
|
||||
switch (special) {
|
||||
case 'SPECIAL_FILL':
|
||||
if (root.currentlyMovedWindow != null) {
|
||||
geometry = root.getFillGeometry(root.currentlyMovedWindow, activeTileIndex == 0);
|
||||
}
|
||||
break;
|
||||
case 'SPECIAL_SPLIT_VERTICAL':
|
||||
if (root.currentlyMovedWindow != null) {
|
||||
geometry = splitAndMoveSplitted(root.currentlyMovedWindow, true, activeTileIndex == 0, false);
|
||||
}
|
||||
break;
|
||||
case 'SPECIAL_SPLIT_HORIZONTAL':
|
||||
if (root.currentlyMovedWindow != null) {
|
||||
geometry = splitAndMoveSplitted(root.currentlyMovedWindow, false, activeTileIndex == 0, false);
|
||||
}
|
||||
break;
|
||||
case 'SPECIAL_NO_TITLEBAR_AND_FRAME':
|
||||
case 'SPECIAL_KEEP_ABOVE':
|
||||
case 'SPECIAL_KEEP_BELOW':
|
||||
case 'SPECIAL_EMPTY':
|
||||
case 'SPECIAL_MINIMIZE':
|
||||
case 'SPECIAL_CLOSE':
|
||||
case 'SPECIAL_AUTO_TILER_TOGGLE':
|
||||
break;
|
||||
case 'SPECIAL_AUTO_TILER_1':
|
||||
case 'SPECIAL_AUTO_TILER_2':
|
||||
case 'SPECIAL_AUTO_TILER_3':
|
||||
if (!layoutRepeater.model[activeLayoutIndex].activeAutoTiler) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
let layout = layoutRepeater.model[activeLayoutIndex].tiles[activeTileIndex];
|
||||
let hintWidth = layout.w == undefined ? layout.pxW : layout.w / 100 * clientArea.width;
|
||||
let hintHeight = layout.h == undefined ? layout.pxH : layout.h / 100 * clientArea.height;
|
||||
let hintX = (layout.x == undefined ? layout.pxX : layout.x / 100 * clientArea.width) - (layout.aX == undefined ? 0 : layout.aX * hintWidth / 100);
|
||||
let hintY = (layout.y == undefined ? layout.pxY : layout.y / 100 * clientArea.height) - (layout.aY == undefined ? 0 : layout.aY * hintHeight / 100);
|
||||
if (root.centerInTile) {
|
||||
popupDropHintWidth = root.currentlyMovedWindow.width;
|
||||
popupDropHintHeight = root.currentlyMovedWindow.height;
|
||||
popupDropHintX = hintX + hintWidth / 2 - root.currentlyMovedWindow.width / 2;
|
||||
popupDropHintY = hintY + hintHeight / 2 - root.currentlyMovedWindow.height / 2;
|
||||
} else {
|
||||
popupDropHintWidth = hintWidth;
|
||||
popupDropHintHeight = hintHeight;
|
||||
popupDropHintX = hintX;
|
||||
popupDropHintY = hintY;
|
||||
}
|
||||
showPopupDropHint = root.config.showTargetTileHint;
|
||||
hasValidPopupDropHint = true;
|
||||
return; // Force return to avoid hiding popup
|
||||
}
|
||||
if (geometry != null) {
|
||||
if (root.centerInTile) {
|
||||
popupDropHintX = (geometry.x - clientArea.x) + geometry.width / 2 - root.currentlyMovedWindow.width / 2;
|
||||
popupDropHintY = (geometry.y - clientArea.y) + geometry.height / 2 - root.currentlyMovedWindow.height / 2;
|
||||
popupDropHintWidth = root.currentlyMovedWindow.width;
|
||||
popupDropHintHeight = root.currentlyMovedWindow.height;
|
||||
shouldShowPopupDropHint = true;
|
||||
} else {
|
||||
popupDropHintX = geometry.x - clientArea.x;
|
||||
popupDropHintY = geometry.y - clientArea.y;
|
||||
popupDropHintWidth = geometry.width;
|
||||
popupDropHintHeight = geometry.height;
|
||||
shouldShowPopupDropHint = true;
|
||||
}
|
||||
}
|
||||
if (root.config.showTargetTileHint) {
|
||||
showPopupDropHint = shouldShowPopupDropHint;
|
||||
} else {
|
||||
showPopupDropHint = false;
|
||||
}
|
||||
hasValidPopupDropHint = shouldShowPopupDropHint;
|
||||
}
|
||||
|
||||
function updateHintContent() {
|
||||
if (activeVirtualDesktopIndex >= 0) {
|
||||
hasValidPopupDropHint = false;
|
||||
showPopupDropHint = false;
|
||||
if (root.virtualDesktops[activeVirtualDesktopIndex].isAdd) {
|
||||
switch (config.virtualDesktopDropAction) {
|
||||
case 0:
|
||||
if (root.moveToVirtualDesktopOnDrop) {
|
||||
// hint = '<b>Drop</b> - Switch to a new virtual desktop, and move window';
|
||||
hint = '<b>Drop</b> - Move window to a new virtual desktop, and switch to it';
|
||||
} else {
|
||||
// hint = '<b>Drop</b> - Add new virtual desktop, and move window';
|
||||
// hint = '<b>Drop</b> - Move window to a new virtual desktop without switching';
|
||||
hint = '<b>Drop</b> - Move window to a new virtual desktop then go back to ' + root.virtualDesktopAtMoveStart.name;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (root.moveToVirtualDesktopOnDrop) {
|
||||
// hint = '<b>Drop</b> - Switch to a new virtual desktop, and maximize window';
|
||||
hint = '<b>Drop</b> - Maximize window on a new virtual desktop, and switch to it';
|
||||
} else {
|
||||
// hint = '<b>Drop</b> - Add new virtual desktop, and maximize window';
|
||||
// hint = '<b>Drop</b> - Maximize window on a new virtual desktop without switching';
|
||||
hint = '<b>Drop</b> - Maximize window on a new virtual desktop then go back to ' + root.virtualDesktopAtMoveStart.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (root.config.hintMoveOnDrop) {
|
||||
hint += ' (<b>' + root.config.shortcutMoveOnDrop + '</b>)';
|
||||
}
|
||||
} else {
|
||||
let virtualDesktopName = root.virtualDesktops[activeVirtualDesktopIndex].desktop.name;
|
||||
let virtualDesktopHoverChanged = activeVirtualDesktopIndex != root.virtualDesktopIndexAtMoveStart;
|
||||
switch (config.virtualDesktopDropAction) {
|
||||
case 0:
|
||||
if (!virtualDesktopHoverChanged) {
|
||||
hint = '<b>Drop</b> - Cancel move';
|
||||
} else if (root.moveToVirtualDesktopOnDrop) {
|
||||
// hint = '<b>Hover</b> - Switch to ' + virtualDesktopName + '<br><b>Drop</b> - Move window, and switch to ' + virtualDesktopName;
|
||||
hint = '<b>Drop</b> - Move window to ' + virtualDesktopName + ', and switch to it';
|
||||
} else {
|
||||
// hint = '<b>Hover</b> - Switch to ' + virtualDesktopName + '<br><b>Drop</b> - Move window to ' + virtualDesktopName;
|
||||
// hint = '<b>Hover</b> - Switch to ' + virtualDesktopName + '<br><b>Drop</b> - Move window to ' + virtualDesktopName + ' without switching';
|
||||
hint = '<b>Drop</b> - Move window to ' + virtualDesktopName + ' then go back to ' + root.virtualDesktopAtMoveStart.name;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (!virtualDesktopHoverChanged) {
|
||||
hint = '<b>Drop</b> - Maximize window on current virtual desktop';
|
||||
} else if (root.moveToVirtualDesktopOnDrop) {
|
||||
// hint = '<b>Hover</b> - Switch to ' + virtualDesktopName + '<br><b>Drop</b> - Maximize window on, and switch to ' + virtualDesktopName;
|
||||
hint = '<b>Drop</b> - Maximize window on ' + virtualDesktopName + ', and switch to it';
|
||||
} else {
|
||||
// hint = '<b>Hover</b> - Switch to ' + virtualDesktopName + '<br><b>Drop</b> - Maximize window on ' + virtualDesktopName;
|
||||
// hint = '<b>Hover</b> - Switch to ' + virtualDesktopName + '<br><b>Drop</b> - Maximize window on ' + virtualDesktopName + ' without switching';
|
||||
hint = '<b>Drop</b> - Maximize window on ' + virtualDesktopName + ' then go back to ' + root.virtualDesktopAtMoveStart.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (virtualDesktopHoverChanged && root.config.hintMoveOnDrop) {
|
||||
hint += ' (<b>' + root.config.shortcutMoveOnDrop + '</b>)';
|
||||
}
|
||||
if (root.currentVirtualDesktopIndex != activeVirtualDesktopIndex) {
|
||||
hint += '<br><b>Hover</b> - Switch to ' + virtualDesktopName;
|
||||
}
|
||||
}
|
||||
} else if (!virtualDesktopVisibilityOverride && root.config.virtualDesktopVisibility == 1) {
|
||||
hint = "Show tiler (<b>" + root.config.shortcutShowAllSpan + "</b>)";
|
||||
hasValidPopupDropHint = false;
|
||||
showPopupDropHint = false;
|
||||
} else if (activeLayoutIndex >= 0 && activeTileIndex >= 0) {
|
||||
updateAndShowPopupDropHint();
|
||||
popupDropHintIsCenterInTile = root.centerInTile;
|
||||
let special = layoutRepeater.model[activeLayoutIndex].special;
|
||||
let tile = layoutRepeater.model[activeLayoutIndex].tiles[activeTileIndex];
|
||||
if (root.centerInTile && hasValidPopupDropHint) {
|
||||
hint = '<b>Center in tile</b> - will not resize the window' + (root.config.hintCenterInTile ? '<br>Toggle with <b>' + root.config.shortcutCenterInTile + '</b>' : '');
|
||||
} else if (tile.hint) {
|
||||
switch (special) {
|
||||
case 'SPECIAL_KEEP_ABOVE':
|
||||
hint = tile.hint + '<br>Currently <b>' + (root.currentlyMovedWindow.keepAbove ? 'Enabled' : 'Disabled') + '</b>';
|
||||
break;
|
||||
case 'SPECIAL_KEEP_BELOW':
|
||||
hint = tile.hint + '<br>Currently <b>' + (root.currentlyMovedWindow.keepBelow ? 'Enabled' : 'Disabled') + '</b>';
|
||||
break;
|
||||
case 'SPECIAL_FILL':
|
||||
hint = hasValidPopupDropHint ? tile.hint : '<font color="orange">⚠</font> No free space available';
|
||||
break;
|
||||
case 'SPECIAL_SPLIT_HORIZONTAL':
|
||||
case 'SPECIAL_SPLIT_VERTICAL':
|
||||
hint = hasValidPopupDropHint ? tile.hint : '<font color="orange">⚠</font> No window available for splitting';
|
||||
break;
|
||||
case 'SPECIAL_AUTO_TILER_TOGGLE':
|
||||
hint = root.currentlyMovedWindow.mt_auto == undefined ? '<b>Enable</b> auto-tiling for this window' : '<b>Disable</b> auto-tiling for this window';
|
||||
break;
|
||||
default:
|
||||
hint = tile.hint;
|
||||
break;
|
||||
}
|
||||
} else if (layoutRepeater.model[activeLayoutIndex].activeAutoTiler == true && tile.t != '*') {
|
||||
hint = 'Auto-tile in this tile<br>Cycle auto-tiled windows with Ctrl+Alt+Left or Right';
|
||||
} else if (root.virtualDesktopChangedSinceMoveStart) {
|
||||
if (root.moveToVirtualDesktopOnTile) {
|
||||
hint = 'Tile window on current virtual dekstop';
|
||||
} else {
|
||||
hint = 'Tile window on ' + Workspace.currentDesktop.name + ' then go back to ' + root.virtualDesktopAtMoveStart.name;
|
||||
}
|
||||
if (root.config.hintMoveOnDrop) {
|
||||
hint += ' (<b>' + root.config.shortcutMoveOnDrop + '</b>)';
|
||||
}
|
||||
} else if ((root.config.showSizeHint || root.config.showPositionHint) && !special) {
|
||||
hint = '';
|
||||
|
||||
if (root.config.showPositionHint) {
|
||||
if (root.config.showPositionHintInPixels) {
|
||||
hint += 'X: <b>' + Math.round(popupDropHintX) + '</b> Y: <b>' + Math.round(popupDropHintY) + '</b>';
|
||||
} else {
|
||||
hint += 'X: <b>' + Math.round(100 * popupDropHintX / clientArea.width) + '</b>% Y: <b>' + Math.round(100 * popupDropHintY / clientArea.height) + '</b>%';
|
||||
}
|
||||
}
|
||||
if (root.config.showSizeHint) {
|
||||
if (hint.length > 0) {
|
||||
hint += '<br>';
|
||||
}
|
||||
if (root.config.showSizeHintInPixels) {
|
||||
hint += 'W: <b>' + Math.round(popupDropHintWidth) + '</b> H: <b>' + Math.round(popupDropHintHeight) + '</b>';
|
||||
} else {
|
||||
hint += 'W: <b>' + Math.round(100 * popupDropHintWidth / clientArea.width) + '</b>% H: <b>' + Math.round(100 * popupDropHintHeight / clientArea.height) + '</b>%';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hint = null;
|
||||
}
|
||||
} else {
|
||||
hasValidPopupDropHint = false;
|
||||
showPopupDropHint = false;
|
||||
hint = null;
|
||||
}
|
||||
|
||||
if (hint == null) {
|
||||
let defaultHint = "";
|
||||
let hasShortcutHint = false;
|
||||
|
||||
if (root.config.showHintHint) {
|
||||
defaultHint += (defaultHint.length > 0 ? " " : "") + "Configure tiler visibility and these hints in settings.<br>";
|
||||
}
|
||||
if (root.config.hintShowAllSpan) {
|
||||
defaultHint += (hasShortcutHint ? " - " : "") + (showAll ? "Show default (<b>" + root.config.shortcutShowAllSpan + "</b>)" : "Show all (<b>" + root.config.shortcutShowAllSpan + "</b>)");
|
||||
hasShortcutHint = true;
|
||||
}
|
||||
if (root.config.hintVisibility) {
|
||||
defaultHint += (hasShortcutHint ? " - " : "") + "Visibility (<b>" + root.config.shortcutVisibility + "</b>)";
|
||||
hasShortcutHint = true;
|
||||
}
|
||||
if (root.config.hintChangeMode) {
|
||||
defaultHint += (hasShortcutHint ? " - " : "") + "Mode (<b>" + root.config.shortcutChangeMode + "</b>)";
|
||||
hasShortcutHint = true;
|
||||
}
|
||||
if (root.config.hintInputType) {
|
||||
defaultHint += (hasShortcutHint ? " - " : "") + "Input type (<b>" + root.config.shortcutInputType + "</b>)";
|
||||
hasShortcutHint = true;
|
||||
}
|
||||
if (root.config.hintCenterInTile) {
|
||||
defaultHint += (hasShortcutHint ? " - " : "") + "Center in tile (<b>" + root.config.shortcutCenterInTile + "</b>)";
|
||||
hasShortcutHint = true;
|
||||
}
|
||||
if (root.config.hintToggleTilingSuggestions) {
|
||||
defaultHint += (hasShortcutHint ? " - " : "") + "Suggestions: <b>" + (settings.showTilingSuggestions ? "Enabled": "Disabled") + "</b> (<b>" + root.config.shortcutToggleTilingSuggestions + "</b>)";
|
||||
hasShortcutHint = true;
|
||||
}
|
||||
|
||||
if (defaultHint.length > 0) {
|
||||
hint = defaultHint;
|
||||
}
|
||||
}
|
||||
|
||||
if (root.useAutoTilerPreview) {
|
||||
if (root.validAutoTilerPreview) {
|
||||
hint = 'Valid auto tile configuration - good job! :)';
|
||||
} else {
|
||||
hint = '<font color="orange">⚠</font> <b>WARNING</b> <font color="orange">⚠</font> INVALID AUTO TILE CONFIGURATION';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateRevealed(forceUpdate = false) {
|
||||
var updatedRevealed;
|
||||
if (revealBox == null) {
|
||||
updatedRevealed = true;
|
||||
} else {
|
||||
let x = root.getCursorPosition().x;
|
||||
let y = root.getCursorPosition().y;
|
||||
updatedRevealed = revealBox.left <= x && revealBox.right >= x && revealBox.top <= y && revealBox.bottom >= y;
|
||||
}
|
||||
|
||||
if (forceUpdate || updatedRevealed != revealed) {
|
||||
revealed = updatedRevealed;
|
||||
root.updateWindowVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: mainItem
|
||||
width: popupTiler.width
|
||||
height: popupTiler.height
|
||||
visible: revealed
|
||||
|
||||
SequentialAnimation {
|
||||
id: showPopupTilerAnimation
|
||||
running: false
|
||||
|
||||
NumberAnimation {
|
||||
target: popupTiler;
|
||||
property: "opacity";
|
||||
from: 0;
|
||||
to: 0;
|
||||
duration: 32;
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: popupTiler;
|
||||
property: "opacity";
|
||||
from: 1;
|
||||
to: 1;
|
||||
duration: 1;
|
||||
}
|
||||
|
||||
onFinished: {
|
||||
root.updateWindowVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
Colors {
|
||||
id: colors
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: popupDropHint
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: popupDropHintX
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: popupDropHintY
|
||||
width: popupDropHintWidth
|
||||
height: popupDropHintHeight
|
||||
border.color: colors.tileBorderColor
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
radius: 12
|
||||
visible: showPopupDropHint
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: colors.hintBackgroundColor
|
||||
radius: 12
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: layouts
|
||||
width: layoutGrid.implicitWidth + layoutGrid.columnSpacing * 2
|
||||
height: layoutGrid.implicitHeight + layoutGrid.rowSpacing * 2
|
||||
color: root.config.gridTilerOpacity != 1 ? Qt.alpha(colors.backgroundColor, root.config.gridTilerOpacity) : colors.backgroundColor
|
||||
border.color: colors.borderColor
|
||||
border.width: 1
|
||||
radius: 8
|
||||
visible: virtualDesktopVisibilityOverride || root.config.virtualDesktopVisibility != 1
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: positionX
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: positionY
|
||||
|
||||
GridLayout {
|
||||
id: layoutGrid
|
||||
columns: showAll ? root.config.gridAllColumns : root.config.gridColumns
|
||||
columnSpacing: root.config.gridSpacing
|
||||
rowSpacing: root.config.gridSpacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.config.gridSpacing
|
||||
uniformCellWidths: true
|
||||
uniformCellHeights: true
|
||||
|
||||
Repeater {
|
||||
id: layoutRepeater
|
||||
model: showAll ? root.popupGridAllLayouts : root.popupGridLayouts
|
||||
|
||||
Rectangle {
|
||||
id: tiles
|
||||
width: root.config.gridWidth
|
||||
height: root.config.gridHeight
|
||||
color: "transparent"
|
||||
border.color: modelData.activeAutoTiler ? colors.tileBorderColor : colors.borderColor
|
||||
border.width: 1
|
||||
radius: 8
|
||||
clip: modelData.clip == true
|
||||
|
||||
property bool layoutActive: activeLayoutIndex == index
|
||||
|
||||
Repeater {
|
||||
id: tileRepeater
|
||||
model: modelData.tiles
|
||||
|
||||
Item {
|
||||
id: tile
|
||||
|
||||
property bool tileActive: activeTileIndex == index
|
||||
property bool tileDisabled: modelData.d ? true : false
|
||||
|
||||
width: (modelData.w == undefined ? modelData.pxW / clientArea.width : modelData.w / 100) * (tiles.width - borderOffset * 2)
|
||||
height: (modelData.h == undefined ? modelData.pxH / clientArea.height : modelData.h / 100) * (tiles.height - borderOffset * 2)
|
||||
x: (modelData.x == undefined ? modelData.pxX / clientArea.width : modelData.x / 100) * (tiles.width - borderOffset * 2) + borderOffset - (modelData.aX == undefined ? 0 : modelData.aX * width / 100)
|
||||
y: (modelData.y == undefined ? modelData.pxY / clientArea.height : modelData.y / 100) * (tiles.height - borderOffset * 2) + borderOffset - (modelData.aY == undefined ? 0 : modelData.aY * height / 100)
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: tilePadding
|
||||
border.color: colors.tileBorderColor
|
||||
border.width: 1
|
||||
// color: "#152030"
|
||||
color: "transparent"
|
||||
radius: 6
|
||||
opacity: tileDisabled ? 0.3 : 1
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: layoutActive && tileActive ? colors.tileBackgroundColorActive : colors.tileBackgroundColor
|
||||
radius: 6
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
color: colors.textColor
|
||||
textFormat: Text.StyledText
|
||||
// ⸰ ·
|
||||
text: root.centerInTile && layoutActive && tileActive && hasValidPopupDropHint ? "⸰" : (modelData.t && modelData.t.length > 0 ? modelData.t : "")
|
||||
font.pixelSize: 14
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: root.centerInTile && layoutActive && tileActive && hasValidPopupDropHint ? true : (modelData.t ? modelData.t : false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rectangle {
|
||||
// id: autoTilerScrollLeft
|
||||
|
||||
// width: 34 + layoutGrid.columnSpacing * 2
|
||||
// height: 34 + layoutGrid.columnSpacing * 2
|
||||
// color: root.config.gridTilerOpacity != 1 ? Qt.alpha(colors.backgroundColor, root.config.gridTilerOpacity) : colors.backgroundColor
|
||||
// border.color: colors.borderColor
|
||||
// border.width: 1
|
||||
// radius: 8
|
||||
// visible: layouts.visible
|
||||
// anchors.verticalCenter: layouts.verticalCenter
|
||||
// anchors.right: layouts.left
|
||||
// anchors.rightMargin: 2
|
||||
|
||||
|
||||
// Text {
|
||||
// anchors.centerIn: parent
|
||||
// color: colors.textColor
|
||||
// textFormat: Text.StyledText
|
||||
// text: "◀"
|
||||
// font.pixelSize: 14
|
||||
// font.family: "Noto Sans"
|
||||
// horizontalAlignment: Text.AlignHCenter
|
||||
// }
|
||||
// }
|
||||
|
||||
// Rectangle {
|
||||
// id: autoTilerScrollRight
|
||||
|
||||
// width: 34 + layoutGrid.columnSpacing * 2
|
||||
// height: 34 + layoutGrid.columnSpacing * 2
|
||||
// color: root.config.gridTilerOpacity != 1 ? Qt.alpha(colors.backgroundColor, root.config.gridTilerOpacity) : colors.backgroundColor
|
||||
// border.color: colors.borderColor
|
||||
// border.width: 1
|
||||
// radius: 8
|
||||
// visible: layouts.visible
|
||||
// anchors.verticalCenter: layouts.verticalCenter
|
||||
// anchors.left: layouts.right
|
||||
// anchors.leftMargin: 2
|
||||
|
||||
|
||||
// Text {
|
||||
// anchors.centerIn: parent
|
||||
// color: colors.textColor
|
||||
// textFormat: Text.StyledText
|
||||
// text: "▶"
|
||||
// font.pixelSize: 14
|
||||
// font.family: "Noto Sans"
|
||||
// horizontalAlignment: Text.AlignHCenter
|
||||
// }
|
||||
// }
|
||||
|
||||
Rectangle {
|
||||
id: virtualDesktop
|
||||
width: layoutGrid.implicitWidth + layoutGrid.columnSpacing * 2
|
||||
height: virtualDesktopLayout.implicitHeight + layoutGrid.rowSpacing * 2
|
||||
color: root.config.gridTilerOpacity != 1 ? Qt.alpha(colors.backgroundColor, root.config.gridTilerOpacity) : colors.backgroundColor
|
||||
border.color: colors.borderColor
|
||||
border.width: 1
|
||||
radius: 8
|
||||
visible: root.virtualDesktopVisibile
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: positionX
|
||||
anchors.top: layouts.visible ? layouts.bottom : parent.top
|
||||
anchors.topMargin: layouts.visible ? 2 : positionY
|
||||
|
||||
GridLayout {
|
||||
id: virtualDesktopLayout
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
rowSpacing: 1
|
||||
columnSpacing: 1
|
||||
columns: layoutGrid.implicitWidth / 35
|
||||
|
||||
Repeater {
|
||||
id: virtualDesktopRepeater
|
||||
model: root.virtualDesktops
|
||||
|
||||
Item {
|
||||
id: virtualDesktop
|
||||
|
||||
property bool currentVirtualDesktop: root.currentVirtualDesktopIndex == index
|
||||
property bool activeVirtualDesktop: activeVirtualDesktopIndex == index
|
||||
|
||||
width: 34
|
||||
height: 34
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: tilePadding
|
||||
border.color: colors.tileBorderColor
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
radius: 6
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: activeVirtualDesktop ? colors.tileBackgroundColorActive : colors.tileBackgroundColor
|
||||
radius: 6
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
color: colors.textColor
|
||||
textFormat: Text.StyledText
|
||||
text: modelData.isAdd ? "+" : "⸰"
|
||||
font.pixelSize: 14
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: modelData.isAdd || currentVirtualDesktop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: popupHint
|
||||
width: layoutGrid.implicitWidth + layoutGrid.columnSpacing * 2
|
||||
height: popupHintText.implicitHeight + layoutGrid.rowSpacing * 2
|
||||
color: root.config.gridTilerOpacity != 1 ? Qt.alpha(colors.backgroundColor, root.config.gridTilerOpacity) : colors.backgroundColor
|
||||
border.color: colors.borderColor
|
||||
border.width: 1
|
||||
radius: 8
|
||||
visible: root.config.showTextHint && hint != null
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: positionX
|
||||
anchors.top: virtualDesktop.visible ? virtualDesktop.bottom : layouts.bottom
|
||||
anchors.topMargin: 2
|
||||
|
||||
Text {
|
||||
id: popupHintText
|
||||
width: parent.width - 4
|
||||
anchors.centerIn: parent
|
||||
color: colors.textColor
|
||||
textFormat: Text.StyledText
|
||||
text: hint != null ? hint : ""
|
||||
font.pixelSize: 12
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: popupWindowCursor
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.getCursorPosition().x - clientArea.x - 6
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: root.getCursorPosition().y - clientArea.y - 6
|
||||
width: 12
|
||||
height: 12
|
||||
border.color: colors.tileBorderColor
|
||||
border.width: 2
|
||||
color: colors.tileBackgroundColorActive
|
||||
radius: 6
|
||||
visible: !root.useMouseCursor
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 2
|
||||
height: 2
|
||||
color: colors.textColor
|
||||
radius: 1
|
||||
opacity: 0.8
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1
|
||||
repeat: false
|
||||
running: popupTiler.visible && !sizeEstablished
|
||||
onTriggered: {
|
||||
sizeEstablished = true;
|
||||
updateScreen(true);
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: root.config.popupGridPollingRate
|
||||
repeat: true
|
||||
running: popupTiler.visible
|
||||
onTriggered: {
|
||||
let forceUpdate = lastShowAll != showAll;
|
||||
|
||||
if (forceUpdate) {
|
||||
if (showAll) {
|
||||
lastShowAll = true;
|
||||
} else {
|
||||
lastShowAll = false;
|
||||
}
|
||||
}
|
||||
updateScreen(forceUpdate);
|
||||
|
||||
updateRevealed();
|
||||
|
||||
let x = root.getCursorPosition().x;
|
||||
let y = root.getCursorPosition().y;
|
||||
let layoutIndex = -1;
|
||||
let tileIndex = -1;
|
||||
let virtualDesktopIndex = -1;
|
||||
|
||||
if (root.config.windowVisibility == 2) {
|
||||
var updatedHovered;
|
||||
let layoutsPosition = layouts.mapToGlobal(Qt.point(0, 0));
|
||||
let visibleHeight = (layouts.visible ? layouts.height : 0) + (virtualDesktop.visible ? virtualDesktop.height : 0) + (layouts.visible && virtualDesktop.visible ? 2 : 0)
|
||||
if (layoutsPosition.x <= x && layoutsPosition.x + layouts.width >= x && layoutsPosition.y <= y && layoutsPosition.y + visibleHeight >= y) {
|
||||
updatedHovered = true;
|
||||
} else {
|
||||
updatedHovered = false;
|
||||
}
|
||||
if (updatedHovered != currentlyHovered) {
|
||||
currentlyHovered = updatedHovered;
|
||||
root.updateWindowVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
if (layouts.visible) {
|
||||
for (let i = 0; i < layoutRepeater.count; i++) {
|
||||
let currentLayout = layoutRepeater.itemAt(i);
|
||||
let currentLayoutPosition = currentLayout.mapToGlobal(Qt.point(0, 0));
|
||||
|
||||
if (currentLayoutPosition.x <= x && currentLayoutPosition.x + currentLayout.width >= x && currentLayoutPosition.y <= y && currentLayoutPosition.y + currentLayout.height >= y) {
|
||||
layoutIndex = i;
|
||||
// if (layoutRepeater.model[layoutIndex].special) {
|
||||
// tileIndex = 0;
|
||||
// } else {
|
||||
//for (let j = 0; j < currentLayout.children.length; j++) {
|
||||
for (let j = currentLayout.children.length - 1; j >= 0; j--) {
|
||||
let currentTile = currentLayout.children[j];
|
||||
// if (currentTile.tileDisabled) {
|
||||
// continue;
|
||||
// }
|
||||
let currentTilePosition = currentTile.mapToGlobal(Qt.point(0, 0));
|
||||
if (currentTilePosition.x <= x && currentTilePosition.x + currentTile.width >= x && currentTilePosition.y <= y && currentTilePosition.y + currentTile.height >= y) {
|
||||
tileIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (root.virtualDesktopVisibile && layoutIndex == -1) {
|
||||
for (let i = 0; i < virtualDesktopRepeater.count; i++) {
|
||||
let currentVirtualDesktop = virtualDesktopRepeater.itemAt(i);
|
||||
let currentVirtualDesktopPosition = currentVirtualDesktop.mapToGlobal(Qt.point(0, 0));
|
||||
if (currentVirtualDesktopPosition.x <= x && currentVirtualDesktopPosition.x + currentVirtualDesktop.width >= x && currentVirtualDesktopPosition.y <= y && currentVirtualDesktopPosition.y + currentVirtualDesktop.height >= y) {
|
||||
virtualDesktopIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let switchVirtualDesktop = virtualDesktopIndex != -1 && !root.virtualDesktops[virtualDesktopIndex].isAdd && virtualDesktopIndex != root.currentVirtualDesktopIndex;
|
||||
if (activeVirtualDesktopIndex != virtualDesktopIndex) {
|
||||
activeVirtualDesktopIndex = virtualDesktopIndex;
|
||||
if (switchVirtualDesktop) {
|
||||
if (config.virtualDesktopHoverTime == 0) {
|
||||
autoTiler.virtualDesktopAboutToChange(); // Notify to remove window from current virtual desktop auto-tiler
|
||||
Workspace.currentDesktop = root.virtualDesktops[activeVirtualDesktopIndex].desktop;
|
||||
} else {
|
||||
activeVirtualDesktopHoverTime = Date.now();
|
||||
}
|
||||
}
|
||||
updateHintContent();
|
||||
} else if (switchVirtualDesktop && config.virtualDesktopHoverTime > 0 && Date.now() - activeVirtualDesktopHoverTime > config.virtualDesktopHoverTime) {
|
||||
autoTiler.virtualDesktopAboutToChange(); // Notify to remove window from current virtual desktop auto-tiler
|
||||
Workspace.currentDesktop = root.virtualDesktops[activeVirtualDesktopIndex].desktop;
|
||||
updateHintContent();
|
||||
}
|
||||
|
||||
// if (layoutIndex == -1) {
|
||||
// let leftScroll = autoTilerScrollLeft.mapToGlobal(Qt.point(0, 0));
|
||||
// let rightScroll = autoTilerScrollRight.mapToGlobal(Qt.point(0, 0));
|
||||
// if (leftScroll.x <= x && leftScroll.x + autoTilerScrollLeft.width >= x && leftScroll.y <= y && leftScroll.y + autoTilerScrollLeft.height >= y) {
|
||||
// logDev('HOVERING LEFT!!!!');
|
||||
// let timeNow = Date.now();
|
||||
// if (scrollLeftTime == 0) {
|
||||
// scrollLeftTime = timeNow + 1000;
|
||||
// } else if (timeNow >= scrollLeftTime) {
|
||||
// autoTiler.modifyPrimaryIndex(-1);
|
||||
// scrollLeftTime = timeNow + 1000;
|
||||
// }
|
||||
// } else if (rightScroll.x <= x && rightScroll.x + autoTilerScrollRight.width >= x && rightScroll.y <= y && rightScroll.y + autoTilerScrollRight.height >= y) {
|
||||
// logDev('HOVERING RIGHT!!!!');
|
||||
// let timeNow = Date.now();
|
||||
// if (scrollLeftTime == 0) {
|
||||
// scrollLeftTime = timeNow + 1000;
|
||||
// } else if (timeNow >= scrollLeftTime) {
|
||||
// autoTiler.modifyPrimaryIndex(-1);
|
||||
// scrollLeftTime = timeNow + 1000;
|
||||
// }
|
||||
// } else {
|
||||
// scrollLeftTime = 0;
|
||||
// scrollRightTime = 0;
|
||||
// }
|
||||
// } else {
|
||||
// scrollLeftTime = 0;
|
||||
// scrollRightTime = 0;
|
||||
// }
|
||||
|
||||
// TODO: Add support for negative values (-)
|
||||
// TODO: Span more than 1 layout if x < 0 || y < 0 || w > 100 || h > 100 to support SPECIAL_EMPTY
|
||||
if (layoutIndex != activeLayoutIndex || tileIndex != activeTileIndex) {
|
||||
activeLayoutIndex = layoutIndex;
|
||||
activeTileIndex = tileIndex;
|
||||
updateHintContent();
|
||||
} else if (popupDropHintIsCenterInTile != root.centerInTile && activeLayoutIndex >= 0 && activeTileIndex >= 0) {
|
||||
updateHintContent();
|
||||
popupDropHintIsCenterInTile = root.centerInTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+517
@@ -0,0 +1,517 @@
|
||||
import QtQuick
|
||||
import org.kde.kwin
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.components as PlasmaComponents
|
||||
|
||||
// Window {
|
||||
PlasmaCore.Dialog {
|
||||
id: windowSuggestions
|
||||
|
||||
property var activeScreen: null
|
||||
property var currentDesktop: null
|
||||
property var currentActivity: null
|
||||
property bool isDefault: true
|
||||
property int layoutIndex: 0
|
||||
property int tileIndex: 0
|
||||
|
||||
property var clientArea: ({width: 1, height: 1, x: 0, y: 0})
|
||||
property var tilePadding: 2
|
||||
property list<var> convertedOverlay: ([])
|
||||
|
||||
property int skipIndex: -1
|
||||
property int activeIndex: -1
|
||||
|
||||
property int suggestionsVisibility: 0
|
||||
property bool suggestionsInsideTile: true
|
||||
property bool excludeOtherScreens: true
|
||||
property bool excludeOtherDesktops: true
|
||||
property bool excludeOtherActivities: true
|
||||
property bool excludeAutoTiled: true
|
||||
property bool excludeMinimized: true
|
||||
|
||||
property int sortMode: 2
|
||||
property int colCount: 1
|
||||
property int rowCount: 1
|
||||
property int cellWidth: 0
|
||||
property int previewHeight: 0
|
||||
property real cellRatio: 0
|
||||
property int cellHeight: 0
|
||||
property int cellBottomMargin: 0
|
||||
property int textSize: 14
|
||||
property int totalWidth: 0
|
||||
property int totalHeight: 0
|
||||
|
||||
property int offsetX: 0
|
||||
property int offsetY: 0
|
||||
|
||||
property int gridSpacing: 20
|
||||
|
||||
property list<var> validWindows: ([])
|
||||
|
||||
width: clientArea.width
|
||||
height: clientArea.height
|
||||
x: clientArea.x
|
||||
y: clientArea.y
|
||||
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.BypassWindowManagerHint
|
||||
// flags: Qt.Tool | Qt.BypassWindowManagerHint | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus
|
||||
// flags: Qt.Tool | Qt.BypassWindowManagerHint | Qt.FramelessWindowHint
|
||||
// color: "transparent" // PlasmaCore.Dialog
|
||||
visible: false
|
||||
// outputOnly: true
|
||||
backgroundHints: PlasmaCore.Types.NoBackground // PlasmaCore.Dialog
|
||||
// type: PlasmaCore.Dialog.OnScreenDisplay
|
||||
location: PlasmaCore.Types.Desktop // PlasmaCore.Dialog
|
||||
|
||||
function init() {
|
||||
suggestionsVisibility = KWin.readConfig("suggestionsVisibility", 0);
|
||||
suggestionsInsideTile = KWin.readConfig("suggestionsMode", 0) == 0;
|
||||
excludeOtherScreens = !KWin.readConfig("suggestOtherScreens", false);
|
||||
excludeOtherDesktops = !KWin.readConfig("suggestOtherDesktops", false);
|
||||
excludeOtherActivities = !KWin.readConfig("suggestOtherActivities", false);
|
||||
excludeAutoTiled = !KWin.readConfig("suggestAutoTiled", false);
|
||||
excludeMinimized = !KWin.readConfig("suggestMinimized", false);
|
||||
}
|
||||
|
||||
function updateValid(addedWindow) {
|
||||
let valid = [];
|
||||
|
||||
for (let i = 0; i < Workspace.stackingOrder.length; i++) {
|
||||
let window = Workspace.stackingOrder[i];
|
||||
if (window == addedWindow) continue;
|
||||
if (!root.isValidWindow(window)) continue;
|
||||
if (window.fullScreen) continue;
|
||||
// if (window.maximizeMode > 0) continue;
|
||||
if (excludeAutoTiled && window.mt_auto) continue;
|
||||
if (excludeMinimized && window.minimized) continue;
|
||||
if (excludeOtherScreens && window.output != activeScreen) continue;
|
||||
if (excludeOtherDesktops && window.desktops.length > 0 && !window.desktops.includes(currentDesktop)) continue;
|
||||
if (excludeOtherActivities && window.activities.length > 0 && !window.activities.includes(currentActivity)) continue;
|
||||
valid.push(window);
|
||||
}
|
||||
|
||||
switch (sortMode) {
|
||||
case 0: // newest focused first
|
||||
valid.reverse();
|
||||
break;
|
||||
case 1: // oldest focused first
|
||||
break;
|
||||
case 2: // a-z
|
||||
valid.sort((a, b) => a.caption.toLowerCase().localeCompare(b.caption.toLowerCase()));
|
||||
break;
|
||||
}
|
||||
|
||||
validWindows = valid;
|
||||
}
|
||||
|
||||
function updateSizes() {
|
||||
let count = validWindows.length;
|
||||
|
||||
log('Valid count: ' + count);
|
||||
|
||||
let usableHeight = suggestionsInsideTile ? convertedOverlay[activeIndex].height : clientArea.height - 180;
|
||||
let usableWidth = suggestionsInsideTile ? convertedOverlay[activeIndex].width : clientArea.width / 2;
|
||||
let wantedRatio = 16 / 9;
|
||||
let ratio = usableWidth / usableHeight;
|
||||
|
||||
if (!suggestionsInsideTile) {
|
||||
if (ratio < wantedRatio) {
|
||||
usableWidth = parseInt(usableWidth);
|
||||
usableHeight = parseInt(usableWidth / wantedRatio);
|
||||
} else {
|
||||
usableHeight = parseInt(usableHeight);
|
||||
usableWidth = parseInt(usableHeight * wantedRatio);
|
||||
}
|
||||
}
|
||||
|
||||
colCount = Math.ceil(Math.sqrt(count));
|
||||
rowCount = Math.ceil(count / colCount);
|
||||
cellWidth = (usableWidth - gridSpacing * (colCount + 1)) / Math.max(colCount, 2);
|
||||
log('CellWidth before: ' + cellWidth);
|
||||
if (suggestionsInsideTile) {
|
||||
if (cellWidth < 320) {
|
||||
colCount = Math.min(count, Math.floor(convertedOverlay[activeIndex].width / 320));
|
||||
} else {
|
||||
colCount = Math.min(count, Math.floor(convertedOverlay[activeIndex].width / cellWidth));
|
||||
}
|
||||
cellWidth = (convertedOverlay[activeIndex].width - gridSpacing * (colCount + 1)) / Math.max(colCount, 2);
|
||||
}
|
||||
log('ColCount: ' + colCount + ' width: ' + cellWidth + ' gridSpacing: ' + gridSpacing + ' width: ' + convertedOverlay[activeIndex].width + ' usable: ' + usableWidth);
|
||||
cellBottomMargin = Kirigami.Units.iconSizes.large / 4;
|
||||
previewHeight = (usableHeight - gridSpacing * (rowCount + 1)) / Math.max(colCount, 2);
|
||||
if (suggestionsInsideTile && previewHeight < 200) {
|
||||
rowCount = Math.ceil(count / colCount);
|
||||
previewHeight = 200;
|
||||
}
|
||||
cellHeight = previewHeight - cellBottomMargin - textSize;
|
||||
totalWidth = suggestionsInsideTile ? convertedOverlay[activeIndex].width : cellWidth * Math.max(colCount, 2) + gridSpacing * (colCount + 1);
|
||||
totalHeight = suggestionsInsideTile ? convertedOverlay[activeIndex].height : previewHeight * rowCount + gridSpacing * (rowCount + 1);
|
||||
cellRatio = cellWidth / previewHeight;
|
||||
log('Count: ' + count + ' rowCount: ' + rowCount + ' colCount: ' + colCount + ' width: ' + usableWidth + ' height: ' + usableHeight + ' ratio: ' + ratio + ' wanted ratio: ' + wantedRatio + ' cell width: ' + cellWidth + ' cell height: ' + cellHeight + ' totalHeight: ' + totalHeight);
|
||||
}
|
||||
|
||||
function showSuggestions(window, screen, virtualDesktop, activity, isDefault, layoutIndex, tileIndex) {
|
||||
log('screen: ' + screen.name + ' virtualDesktop: ' + virtualDesktop.id + ' activity: ' + activity + ' isDefault: ' + isDefault + ' layoutIndex: ' + layoutIndex + ' tileIndex: ' + tileIndex);
|
||||
activeScreen = screen;
|
||||
currentDesktop = virtualDesktop;
|
||||
currentActivity = activity;
|
||||
windowSuggestions.isDefault = isDefault;
|
||||
windowSuggestions.layoutIndex = layoutIndex;
|
||||
windowSuggestions.tileIndex = tileIndex;
|
||||
|
||||
clientArea = Workspace.clientArea(KWin.FullScreenArea, activeScreen, currentDesktop);
|
||||
activeIndex = 0;
|
||||
skipIndex = tileIndex;
|
||||
|
||||
convertLayoutToScreen();
|
||||
|
||||
updateValid(window);
|
||||
|
||||
if (validWindows.length > 0 && convertedOverlay.length > 0) {
|
||||
updateSizes();
|
||||
updateOffsets();
|
||||
windowSuggestions.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
function convertLayoutToScreen() {
|
||||
let layout = isDefault ? popupGridLayouts[layoutIndex].tiles : popupGridAllLayouts[layoutIndex].tiles;
|
||||
log('Window suggestions layout to convert: ' + JSON.stringify(layout));
|
||||
let converted = [];
|
||||
for (let i = 0; i < layout.length; i++) {
|
||||
if (i == skipIndex) continue;
|
||||
let tile = layout[i];
|
||||
let width = (tile.pxW == undefined ? tile.w / 100 * windowSuggestions.width : tile.pxW);
|
||||
let height = (tile.pxH == undefined ? tile.h / 100 * windowSuggestions.height : tile.pxH);
|
||||
|
||||
// Temporarily add clientArea x/y since it is needed for calculating margins
|
||||
let geometry = {
|
||||
x: clientArea.x + ((tile.pxX == undefined ? tile.x / 100 * windowSuggestions.width : tile.pxX) - (tile.aX == undefined ? 0 : tile.aX * width / 100)),
|
||||
y: clientArea.y + ((tile.pxY == undefined ? tile.y / 100 * windowSuggestions.height : tile.pxY) - (tile.aY == undefined ? 0 : tile.aY * height / 100)),
|
||||
width: width,
|
||||
height: height,
|
||||
tileIndex: i
|
||||
};
|
||||
root.addMargins(geometry, true, true, true, true);
|
||||
geometry.x -= clientArea.x;
|
||||
geometry.y -= clientArea.y;
|
||||
converted.push(geometry);
|
||||
}
|
||||
windowSuggestions.convertedOverlay = converted;
|
||||
}
|
||||
|
||||
function updateOffsets() {
|
||||
if (activeIndex < convertedOverlay.length) {
|
||||
if (suggestionsInsideTile) {
|
||||
offsetX = convertedOverlay[activeIndex].x;
|
||||
offsetY = convertedOverlay[activeIndex].y;
|
||||
} else {
|
||||
let overlay = convertedOverlay[activeIndex];
|
||||
let rightSpace = clientArea.width - overlay.x - overlay.width;
|
||||
if (overlay.x < rightSpace) {
|
||||
offsetX = Math.min(clientArea.width - rightSpace + 2, clientArea.width - totalWidth - 2);
|
||||
} else {
|
||||
offsetX = Math.max(overlay.x - totalWidth - 2, 2);
|
||||
}
|
||||
|
||||
offsetY = overlay.y - ((totalHeight + 80 - overlay.height) / 2);
|
||||
if (offsetY < 0) {
|
||||
offsetY = 0;
|
||||
} else if (offsetY + totalHeight + 80 > clientArea.height) {
|
||||
offsetY = clientArea.height - totalHeight - 80;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectSuggestion(index, tileIndex) {
|
||||
log('Select suggestion: ' + index + ' ' + tileIndex);
|
||||
activeIndex = index;
|
||||
if (suggestionsInsideTile) {
|
||||
updateSizes();
|
||||
}
|
||||
updateOffsets();
|
||||
}
|
||||
|
||||
function addWindowToSelected(window) {
|
||||
log('Selected window caption: ' + window.caption);
|
||||
|
||||
if (activeIndex != -1 && validWindows.length > 0) {
|
||||
let localWindows = [...validWindows];
|
||||
let overlays = JSON.parse(JSON.stringify(windowSuggestions.convertedOverlay)); // Workaround for a strange bug where wrong item is fetched even if activeIndex is correct
|
||||
let geometry = overlays.splice(activeIndex, 1)[0];
|
||||
windowSuggestions.convertedOverlay = [...overlays];
|
||||
geometry.x += clientArea.x;
|
||||
geometry.y += clientArea.y;
|
||||
let index = localWindows.indexOf(window);
|
||||
if (index != -1) {
|
||||
localWindows.splice(index, 1);
|
||||
|
||||
if (!window.desktops.includes(currentDesktop)) {
|
||||
window.desktops = [currentDesktop];
|
||||
}
|
||||
if (!window.activities.includes(currentActivity)) {
|
||||
window.activities = [currentActivity];
|
||||
}
|
||||
if (window.mt_auto) {
|
||||
autoTiler.disableAutoTiling(window);
|
||||
}
|
||||
if (window.minimized) {
|
||||
window.minimized = false;
|
||||
}
|
||||
if (window.maximizeMode > 0) {
|
||||
window.setMaximize(false, false);
|
||||
}
|
||||
if (!window.mt_originalSize) {
|
||||
window.mt_originalSize = {x: window.x, y: window.y, width: window.width, height: window.height};
|
||||
}
|
||||
root.moveAndResizeWindow(window, geometry);
|
||||
Workspace.raiseWindow(window);
|
||||
|
||||
activeIndex = 0;
|
||||
|
||||
if (localWindows.length == 0 || convertedOverlay.length == 0) {
|
||||
windowSuggestions.visible = false;
|
||||
validWindows = [];
|
||||
} else {
|
||||
validWindows = localWindows;
|
||||
if (suggestionsInsideTile) {
|
||||
updateSizes();
|
||||
}
|
||||
updateOffsets();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function windowClosed(window) {
|
||||
log('Closed window caption: ' + window.caption);
|
||||
|
||||
if (activeIndex != -1 && validWindows.length > 0) {
|
||||
let localWindows = [...validWindows];
|
||||
let index = localWindows.indexOf(window);
|
||||
if (index != -1) {
|
||||
localWindows.splice(index, 1);
|
||||
|
||||
if (localWindows.length == 0) {
|
||||
validWindows = [];
|
||||
} else {
|
||||
validWindows = localWindows;
|
||||
if (suggestionsInsideTile) {
|
||||
updateSizes();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: mainItem
|
||||
width: windowSuggestions.width
|
||||
height: windowSuggestions.height
|
||||
|
||||
TapHandler {
|
||||
onTapped: windowSuggestions.visible = false;
|
||||
}
|
||||
|
||||
Colors {
|
||||
id: colors
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: tileRepeater
|
||||
model: windowSuggestions.convertedOverlay
|
||||
|
||||
Item {
|
||||
id: tile
|
||||
|
||||
property bool active: activeIndex == index
|
||||
property int tileIndex: modelData.tileIndex
|
||||
|
||||
x: modelData.x
|
||||
y: modelData.y
|
||||
width: modelData.width
|
||||
height: modelData.height
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: tilePadding
|
||||
border.color: colors.tileBorderColor
|
||||
border.width: 2
|
||||
color: active ? colors.tileBackgroundColorActive : colors.tileBackgroundColorIntense
|
||||
radius: 12
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
color: colors.overlayTextColor
|
||||
textFormat: Text.StyledText
|
||||
text: "<b>Select a window to tile here</b>"
|
||||
font.pixelSize: 16
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: active && !suggestionsInsideTile
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: selectSuggestion(index, tileIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: suggestionsInsideTile ? totalHeight : totalHeight + 80
|
||||
width: totalWidth
|
||||
anchors.top: parent.top
|
||||
// anchors.topMargin: (clientArea.height - height) / 2
|
||||
anchors.topMargin: offsetY
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: offsetX
|
||||
|
||||
Rectangle {
|
||||
id: cellWrapper
|
||||
width: totalWidth
|
||||
height: suggestionsInsideTile ? totalHeight : totalHeight + 80
|
||||
color: suggestionsInsideTile ? "transparent" : "#BB000000"
|
||||
border.width: 1
|
||||
border.color: suggestionsInsideTile ? "transparent" : "#80FFFFFF"
|
||||
radius: 6
|
||||
|
||||
GridView {
|
||||
id: listView
|
||||
model: validWindows
|
||||
width: colCount * (windowSuggestions.cellWidth + gridSpacing)
|
||||
// height: rowCount * (previewHeight + gridSpacing)
|
||||
height: suggestionsInsideTile ? Math.min((previewHeight + gridSpacing) * rowCount, totalHeight - 80 - gridSpacing * 2) : totalHeight - 80 - gridSpacing * 2
|
||||
cellWidth: windowSuggestions.cellWidth + gridSpacing
|
||||
cellHeight: previewHeight + gridSpacing
|
||||
interactive: suggestionsInsideTile ? true : false
|
||||
clip: suggestionsInsideTile
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: suggestionsInsideTile ? (cellWrapper.height - height) / 2 : 40 + gridSpacing
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: suggestionsInsideTile ? (cellWrapper.width + gridSpacing - width) / 2 : gridSpacing
|
||||
|
||||
delegate: Rectangle {
|
||||
width: windowSuggestions.cellWidth
|
||||
height: previewHeight
|
||||
color: "transparent"
|
||||
|
||||
property real previewRatio: modelData.width / modelData.height
|
||||
property int previewActualWidth: previewRatio > cellRatio ? windowSuggestions.cellWidth : windowSuggestions.cellHeight * previewRatio
|
||||
property int previewActualHeight: previewRatio > cellRatio ? windowSuggestions.cellWidth / previewRatio : windowSuggestions.cellHeight
|
||||
|
||||
WindowThumbnail {
|
||||
id: preview
|
||||
client: modelData
|
||||
width: previewActualWidth
|
||||
height: previewActualHeight
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -((textSize + cellBottomMargin) / 2)
|
||||
|
||||
TapHandler {
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: addWindowToSelected(modelData);
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
id: icon
|
||||
width: Kirigami.Units.iconSizes.large
|
||||
height: Kirigami.Units.iconSizes.large
|
||||
source: modelData.icon
|
||||
anchors.horizontalCenter: preview.horizontalCenter
|
||||
anchors.verticalCenter: preview.bottom
|
||||
anchors.verticalCenterOffset: -Math.round(height / 4)
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: text
|
||||
width: windowSuggestions.cellWidth
|
||||
height: textSize
|
||||
text: modelData.caption
|
||||
anchors.top: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
color: "white"
|
||||
|
||||
background: Rectangle {
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: 3
|
||||
height: parent.height + 4
|
||||
width: parent.contentWidth + 6
|
||||
color: "#66000000"
|
||||
radius: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: suggestionsInsideTile ? 4 : 1
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: suggestionsInsideTile ? 4 : 1
|
||||
width: suggestionsInsideTile ? totalWidth - 8 : totalWidth - 2
|
||||
height: 40;
|
||||
color: "#EE333333"
|
||||
radius: suggestionsInsideTile ? 12 : 6
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
color: "white"
|
||||
textFormat: Text.StyledText
|
||||
text: suggestionsInsideTile ? "Select a window to place here" : "Select a window to place in the highlighted tile"
|
||||
font.pixelSize: 16
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: "white"
|
||||
textFormat: Text.StyledText
|
||||
text: "✖"
|
||||
font.pixelSize: 16
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: windowSuggestions.visible = false;
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: suggestionsInsideTile ? 4 : 1
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: suggestionsInsideTile ? 4 : 1
|
||||
width: suggestionsInsideTile ? totalWidth - 8 : totalWidth - 2
|
||||
height: 40;
|
||||
color: "#EE333333"
|
||||
radius: suggestionsInsideTile ? 12 : 6
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
color: "white"
|
||||
textFormat: Text.StyledText
|
||||
text: "Click a tile to switch to it. Click anywhere else to close suggestions. Disable suggestions (<b>" + config.shortcutToggleTilingSuggestions + "</b>)"
|
||||
font.pixelSize: 16
|
||||
font.family: "Noto Sans"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: windowSuggestions.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3880
File diff suppressed because it is too large
Load Diff
+1781
File diff suppressed because it is too large
Load Diff
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"KPackageStructure": "KWin/Script",
|
||||
"KPlugin": {
|
||||
"Authors": [
|
||||
{
|
||||
"Name": "rxappdev"
|
||||
}
|
||||
],
|
||||
"Name": "Mouse Tiler",
|
||||
"Description": "Tile your windows with minimal effort",
|
||||
"Icon": "preferences-desktop-virtual",
|
||||
"Id": "mousetiler",
|
||||
"Version": "6.4.0",
|
||||
"License": "GPLv3",
|
||||
"Website": "https://github.com/rxappdev/MouseTiler"
|
||||
},
|
||||
"X-Plasma-API": "declarativescript",
|
||||
"X-Plasma-MainScript": "ui/main.qml",
|
||||
"X-KDE-ConfigModule": "kwin/effects/configs/kcm_kwin4_genericscripted"
|
||||
}
|
||||
Reference in New Issue
Block a user