show biggest app icon on workspaces, faster keybinds

This commit is contained in:
end-4 2025-04-26 23:50:46 +02:00
parent f52ba7ad2b
commit 5e8f4048da
14 changed files with 225 additions and 83 deletions

View file

@ -160,21 +160,27 @@ bind = Alt, Tab, bringactivetotop, # [hidden] bring it to the top
bindr = Ctrl+Super, R, exec, killall ags agsv1 gjs ydotool; agsv1 & # Restart widgets
bindr = Ctrl+Super+Alt, R, exec, hyprctl reload; killall agsv1 ydotool; agsv1 & # [hidden]
bind = Ctrl+Alt, Slash, exec, agsv1 run-js 'cycleMode();' # Cycle bar mode (normal, focus)
bindir = Super, Super_L, exec, qs ipc call overview toggle || agsv1 -t 'overview' # Toggle overview/launcher
bind = Super, Tab, exec, qs ipc call overview toggle || agsv1 -t 'overview' # [hidden]
bindr = Super, Super_L, exec, qs ipc call overview toggle || agsv1 -t 'overview' # Toggle overview/launcher
# bind = Super, Tab, exec, qs ipc call overview toggle || agsv1 -t 'overview' # [hidden]
bind = Super, Slash, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do agsv1 -t "cheatsheet""$i"; done # Show cheatsheet
bind = Super, B, exec, qs ipc call sidebarLeft toggle || agsv1 -t 'sideleft' # Toggle left sidebar
bind = Super, A, exec, qs ipc call sidebarLeft toggle || agsv1 -t 'sideleft' # [hidden]
bind = Super, O, exec, qs ipc call sidebarLeft toggle || agsv1 -t 'sideleft' # [hidden]
bind = Super, N, exec, qs ipc call sidebarRight toggle || agsv1 -t 'sideright' # Toggle right sidebar
# bind = Super, N, exec, qs ipc call sidebarRight toggle || agsv1 -t 'sideright' # Toggle right sidebar
bind = Super, M, exec, agsv1 run-js 'openMusicControls.value = (!mpris.getPlayer() ? false : !openMusicControls.value);' # Toggle music controls
bind = Super, Comma, exec, agsv1 run-js 'openColorScheme.value = true; Utils.timeout(2000, () => openColorScheme.value = false);' # View color scheme and options
bind = Super, K, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do agsv1 -t "osk""$i"; done # Toggle on-screen keyboard
bind = Ctrl+Alt, Delete, exec, qs ipc call session toggle || for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do agsv1 -t "session""$i"; done # Toggle power menu
# bind = Ctrl+Alt, Delete, exec, qs ipc call session toggle || for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do agsv1 -t "session""$i"; done # Toggle power menu
bind = Ctrl+Super, G, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do agsv1 -t "crosshair""$i"; done # Toggle crosshair
bindle=, XF86MonBrightnessUp, exec, qs ipc call brightness increment || agsv1 run-js 'brightness.screen_value += 0.05; indicator.popup(1);' # [hidden]
bindle=, XF86MonBrightnessDown, exec, qs ipc call brightness decrement || agsv1 run-js 'brightness.screen_value -= 0.05; indicator.popup(1);' # [hidden]
# bind = Super, Super_L, global, quickshell:overviewToggleRelease
bindit = ,Super_L, global, quickshell:workspaceNumber
bind = Super, Tab, global, quickshell:overviewToggle
bind = Super, N, global, quickshell:sidebarRightToggle
bind = Ctrl+Alt, Delete, global, quickshell:sessionToggle
# Testing
bind = Super+Alt, f11, exec, bash -c 'RANDOM_IMAGE=$(find ~/Pictures -type f | grep -v -i "nipple" | grep -v -i "pussy" | shuf -n 1); ACTION=$(notify-send "Test notification with body image" "This notification should contain your user account <b>image</b> and <a href=\"https://discord.com/app\">Discord</a> <b>icon</b>. Oh and here is a random image in your Pictures folder: <img src=\"$RANDOM_IMAGE\" alt=\"Testing image\"/>" -p -h "string:image-path:/var/lib/AccountsService/icons/$USER" -t 6000 -i "discord" -A "openImage=Open profile image" -A "action2=Open the random image" -A "action3=Useless button"); [[ $ACTION == *openImage ]] && xdg-open "/var/lib/AccountsService/icons/$USER"; [[ $ACTION == *action2 ]] && xdg-open \"$RANDOM_IMAGE\"' # [hidden]
bind = Super+Alt, f12, exec, bash -c 'ACTION=$(notify-send "Test notification" "This notification should contain your user account <b>image</b> and <a href=\"https://discord.com/app\">Discord</a> <b>icon</b>.\n<i>Flick right to dismiss!</i>" -p -h "string:image-path:/var/lib/AccountsService/icons/$USER" -t 6000 -i "discord" -A "openImage=Open profile image" -A "action2=Useless button" -A "action3=Cry more"); [[ $ACTION == *openImage ]] && xdg-open "/var/lib/AccountsService/icons/$USER"; [[ $ACTION == *action2 ]] && xdg-open \"$RANDOM_IMAGE\"' # [hidden]
@ -214,3 +220,5 @@ bind = Super+Alt, Slash, exec, pkill fuzzel || fuzzel # Toggle fallback launcher
bind = Ctrl+Super, Backslash, resizeactive, exact 640 480 # [hidden]

View file

@ -1,9 +1,37 @@
import "root:/modules/common/"
import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property int sidebarRightOpenCount: 0
property bool overviewOpen: false
property bool workspaceShowNumbers: false
Timer {
id: workspaceShowNumbersTimer
interval: ConfigOptions.bar.workspaces.showNumberDelay
// interval: 0
repeat: false
onTriggered: {
workspaceShowNumbers = true
}
}
GlobalShortcut {
name: "workspaceNumber"
description: "Hold to show workspace numbers, release to show icons"
onPressed: {
workspaceShowNumbersTimer.start()
}
onReleased: {
workspaceShowNumbersTimer.stop()
workspaceShowNumbers = false
}
}
}

View file

@ -1,8 +1,10 @@
import "root:/modules/common/"
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.SystemTray
import Quickshell.Widgets
import Qt5Compat.GraphicalEffects
MouseArea {
id: root
@ -21,9 +23,9 @@ MouseArea {
item.activate();
break;
case Qt.RightButton:
if (item.hasMenu)
menu.open();
if (item.hasMenu) menu.open();
event.accepted = true;
break;
}
}
@ -39,10 +41,17 @@ MouseArea {
}
IconImage {
id: trayIcon
source: root.item.icon
anchors.centerIn: parent
width: parent.width
height: parent.height
}
ColorOverlay {
anchors.fill: trayIcon
source: trayIcon
color: Appearance.colors.colOnLayer0
}
}

View file

@ -1,5 +1,8 @@
import "root:/"
import "root:/services/"
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/icons.js" as Icons
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
@ -7,18 +10,21 @@ import Quickshell
import Quickshell.Wayland
import Quickshell.Hyprland
import Quickshell.Io
import Quickshell.Widgets
import Qt5Compat.GraphicalEffects
Item {
required property var bar
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen)
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / ConfigOptions.bar.workspacesShown)
readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / ConfigOptions.bar.workspaces.shown)
property list<bool> workspaceOccupied: []
property int widgetPadding: 4
property int workspaceButtonWidth: 26
property int workspaceIconSize: workspaceButtonWidth * 0.8
property int activeWorkspaceMargin: 1
property double animatedActiveWorkspaceIndex: (monitor.activeWorkspace?.id - 1) % ConfigOptions.bar.workspacesShown
property double animatedActiveWorkspaceIndex: (monitor.activeWorkspace?.id - 1) % ConfigOptions.bar.workspaces.shown
Behavior on animatedActiveWorkspaceIndex {
NumberAnimation {
@ -30,8 +36,8 @@ Item {
// Function to update workspaceOccupied
function updateWorkspaceOccupied() {
workspaceOccupied = Array.from({ length: ConfigOptions.bar.workspacesShown }, (_, i) => {
return Hyprland.workspaces.values.some(ws => ws.id === workspaceGroup * ConfigOptions.bar.workspacesShown + i + 1);
workspaceOccupied = Array.from({ length: ConfigOptions.bar.workspaces.shown }, (_, i) => {
return Hyprland.workspaces.values.some(ws => ws.id === workspaceGroup * ConfigOptions.bar.workspaces.shown + i + 1);
})
}
@ -91,7 +97,7 @@ Item {
implicitHeight: 40
Repeater {
model: ConfigOptions.bar.workspacesShown
model: ConfigOptions.bar.workspaces.shown
Rectangle {
z: 1
@ -156,7 +162,7 @@ Item {
implicitHeight: 40
Repeater {
model: ConfigOptions.bar.workspacesShown
model: ConfigOptions.bar.workspaces.shown
Button {
id: button
@ -165,19 +171,31 @@ Item {
width: workspaceButtonWidth
background: Item {
id: workspaceButtonBackground
implicitWidth: workspaceButtonWidth
implicitHeight: workspaceButtonWidth
property int workspaceValue: workspaceGroup * ConfigOptions.bar.workspaces.shown + index + 1
property var biggestWindow: {
const windowsInThisWorkspace = HyprlandData.windowList.filter(w => w.workspace.id == workspaceButtonBackground.workspaceValue)
return windowsInThisWorkspace.reduce((maxWin, win) => {
const maxArea = (maxWin?.size?.[0] ?? 0) * (maxWin?.size?.[1] ?? 0)
const winArea = (win?.size?.[0] ?? 0) * (win?.size?.[1] ?? 0)
return winArea > maxArea ? win : maxWin
}, null)
}
property var mainAppIconSource: Quickshell.iconPath(Icons.noKnowledgeIconGuess(biggestWindow?.class))
StyledText {
opacity: (ConfigOptions.bar.workspaces.alwaysShowNumbers || GlobalStates.workspaceShowNumbers || !workspaceButtonBackground.biggestWindow) ? 1 : 0
z: 3
property int workspaceValue: workspaceGroup * ConfigOptions.bar.workspacesShown + index + 1
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: Appearance.font.pixelSize.small - ((text.length - 1) * (text !== "10") * 2)
text: `${workspaceValue}`
text: `${workspaceButtonBackground.workspaceValue}`
elide: Text.ElideRight
color: (monitor.activeWorkspace?.id == workspaceValue) ? Appearance.m3colors.m3onPrimary : (workspaceOccupied[index] ? Appearance.colors.colOnLayer1 : Appearance.colors.colOnLayer1Inactive)
color: (monitor.activeWorkspace?.id == workspaceButtonBackground.workspaceValue) ? Appearance.m3colors.m3onPrimary : (workspaceOccupied[index] ? Appearance.colors.colOnLayer1 : Appearance.colors.colOnLayer1Inactive)
Behavior on color {
ColorAnimation {
@ -187,6 +205,27 @@ Item {
}
Behavior on opacity {
NumberAnimation {
duration: Appearance.animation.elementDecelFast.duration
easing.type: Appearance.animation.elementDecelFast.type
}
}
}
IconImage {
id: mainAppIcon
opacity: (workspaceButtonBackground.biggestWindow && !GlobalStates.workspaceShowNumbers && !ConfigOptions.bar.workspaces.alwaysShowNumbers) ? 1 : 0
source: workspaceButtonBackground.mainAppIconSource
anchors.centerIn: parent
implicitSize: workspaceIconSize
Behavior on opacity {
NumberAnimation {
duration: Appearance.animation.elementDecelFast.duration
easing.type: Appearance.animation.elementDecelFast.type
}
}
}
}

View file

@ -26,64 +26,64 @@ Singleton {
m3colors: QtObject {
property bool darkmode: false
property bool transparent: false
property color m3primary_paletteKeyColor: "#8A7175"
property color m3secondary_paletteKeyColor: "#847376"
property color m3tertiary_paletteKeyColor: "#8F6E74"
property color m3neutral_paletteKeyColor: "#7B7676"
property color m3neutral_variant_paletteKeyColor: "#7B7676"
property color m3background: "#FFF8F7"
property color m3onBackground: "#1E1B1B"
property color m3surface: "#FFF8F7"
property color m3surfaceDim: "#E0D8D8"
property color m3surfaceBright: "#FFF8F7"
property color m3surfaceContainerLowest: "#FFFFFF"
property color m3surfaceContainerLow: "#FAF2F2"
property color m3surfaceContainer: "#F4ECEC"
property color m3surfaceContainerHigh: "#EEE6E6"
property color m3surfaceContainerHighest: "#E8E1E1"
property color m3onSurface: "#1E1B1B"
property color m3surfaceVariant: "#E8E1E1"
property color m3onSurfaceVariant: "#4A4646"
property color m3inverseSurface: "#332F30"
property color m3inverseOnSurface: "#F7EFEF"
property color m3outline: "#797373"
property color m3outlineVariant: "#CCC5C5"
property color m3primary_paletteKeyColor: "#91689E"
property color m3secondary_paletteKeyColor: "#837186"
property color m3tertiary_paletteKeyColor: "#9D6A67"
property color m3neutral_paletteKeyColor: "#7C757B"
property color m3neutral_variant_paletteKeyColor: "#7D747D"
property color m3background: "#161217"
property color m3onBackground: "#EAE0E7"
property color m3surface: "#161217"
property color m3surfaceDim: "#161217"
property color m3surfaceBright: "#3D373D"
property color m3surfaceContainerLowest: "#110D12"
property color m3surfaceContainerLow: "#1F1A1F"
property color m3surfaceContainer: "#231E23"
property color m3surfaceContainerHigh: "#2D282E"
property color m3surfaceContainerHighest: "#383339"
property color m3onSurface: "#EAE0E7"
property color m3surfaceVariant: "#4C444D"
property color m3onSurfaceVariant: "#CFC3CD"
property color m3inverseSurface: "#EAE0E7"
property color m3inverseOnSurface: "#342F34"
property color m3outline: "#988E97"
property color m3outlineVariant: "#4C444D"
property color m3shadow: "#000000"
property color m3scrim: "#000000"
property color m3surfaceTint: "#70585D"
property color m3primary: "#70585D"
property color m3onPrimary: "#FFFFFF"
property color m3primaryContainer: "#FADBE0"
property color m3onPrimaryContainer: "#564145"
property color m3inversePrimary: "#DDBFC4"
property color m3secondary: "#6A5A5D"
property color m3onSecondary: "#FFFFFF"
property color m3secondaryContainer: "#F3DDE0"
property color m3onSecondaryContainer: "#524346"
property color m3tertiary: "#8D6C72"
property color m3onTertiary: "#FFFFFF"
property color m3tertiaryContainer: "#8D6C72"
property color m3onTertiaryContainer: "#FFFFFF"
property color m3error: "#BA1A1A"
property color m3onError: "#FFFFFF"
property color m3errorContainer: "#FFDAD6"
property color m3onErrorContainer: "#93000A"
property color m3primaryFixed: "#FADBE0"
property color m3primaryFixedDim: "#DDBFC4"
property color m3onPrimaryFixed: "#28171A"
property color m3onPrimaryFixedVariant: "#564145"
property color m3secondaryFixed: "#F3DDE0"
property color m3secondaryFixedDim: "#D6C2C4"
property color m3onSecondaryFixed: "#24191B"
property color m3onSecondaryFixedVariant: "#524346"
property color m3tertiaryFixed: "#FFD9DF"
property color m3tertiaryFixedDim: "#E4BDC3"
property color m3onTertiaryFixed: "#2B151A"
property color m3onTertiaryFixedVariant: "#5B3F45"
property color m3success: "#4F6354"
property color m3onSuccess: "#FFFFFF"
property color m3successContainer: "#D1E8D5"
property color m3onSuccessContainer: "#0C1F13"
property color m3surfaceTint: "#E5B6F2"
property color m3primary: "#E5B6F2"
property color m3onPrimary: "#452152"
property color m3primaryContainer: "#5D386A"
property color m3onPrimaryContainer: "#F9D8FF"
property color m3inversePrimary: "#775084"
property color m3secondary: "#D5C0D7"
property color m3onSecondary: "#392C3D"
property color m3secondaryContainer: "#534457"
property color m3onSecondaryContainer: "#F2DCF3"
property color m3tertiary: "#F5B7B3"
property color m3onTertiary: "#4C2523"
property color m3tertiaryContainer: "#BA837F"
property color m3onTertiaryContainer: "#000000"
property color m3error: "#FFB4AB"
property color m3onError: "#690005"
property color m3errorContainer: "#93000A"
property color m3onErrorContainer: "#FFDAD6"
property color m3primaryFixed: "#F9D8FF"
property color m3primaryFixedDim: "#E5B6F2"
property color m3onPrimaryFixed: "#2E0A3C"
property color m3onPrimaryFixedVariant: "#5D386A"
property color m3secondaryFixed: "#F2DCF3"
property color m3secondaryFixedDim: "#D5C0D7"
property color m3onSecondaryFixed: "#241727"
property color m3onSecondaryFixedVariant: "#514254"
property color m3tertiaryFixed: "#FFDAD7"
property color m3tertiaryFixedDim: "#F5B7B3"
property color m3onTertiaryFixed: "#331110"
property color m3onTertiaryFixedVariant: "#663B39"
property color m3success: "#B5CCBA"
property color m3onSuccess: "#213528"
property color m3successContainer: "#374B3E"
property color m3onSuccessContainer: "#D1E9D6"
property color term0: "#EDE4E4"
property color term1: "#B52755"
property color term2: "#A97363"

View file

@ -18,12 +18,16 @@ Singleton {
}
property QtObject bar: QtObject {
property int workspacesShown: 10
property int batteryLowThreshold: 20
property QtObject resources: QtObject {
property bool alwaysShowSwap: true
property bool alwaysShowCpu: false
}
property QtObject workspaces: QtObject {
property int shown: 10
property bool alwaysShowNumbers: false
property int showNumberDelay: 150 // milliseconds
}
}
property QtObject osd: QtObject {

View file

@ -25,7 +25,7 @@ Item {
Process {
id: closeSidebarProcess
command: ["bash", "-c", `qs ipc call sidebarRight close`]
command: ["qs", "ipc", "call", "sidebarRight", "close"]
}
Process {

View file

@ -113,4 +113,21 @@ Scope {
}
}
GlobalShortcut {
name: "overviewToggle"
description: "Toggles overview on press"
onPressed: {
GlobalStates.overviewOpen = !GlobalStates.overviewOpen
}
}
GlobalShortcut {
name: "overviewToggleRelease"
description: "Toggles overview on release"
onReleased: {
GlobalStates.overviewOpen = !GlobalStates.overviewOpen
}
}
}

View file

@ -9,7 +9,6 @@ import Quickshell.Io
import Quickshell.Widgets
import Quickshell.Wayland
import Quickshell.Hyprland
import "./icons.js" as Icons
Item {
id: root
@ -128,7 +127,7 @@ Item {
Repeater { // Window repeater
model: windowAddresses.filter((address) => {
var win = windowByAddress[address]
return (root.workspaceGroup * root.workspacesShown < win.workspace.id && win.workspace.id <= (root.workspaceGroup + 1) * root.workspacesShown)
return (root.workspaceGroup * root.workspacesShown < win?.workspace?.id && win?.workspace?.id <= (root.workspaceGroup + 1) * root.workspacesShown)
})
delegate: OverviewWindow {
id: window

View file

@ -1,3 +1,4 @@
import "root:/modules/common/functions/icons.js" as Icons
import "root:/services/"
import "root:/modules/common"
import "root:/modules/common/widgets"
@ -8,7 +9,6 @@ import Quickshell
import Quickshell.Widgets
import Quickshell.Io
import Quickshell.Hyprland
import "./icons.js" as Icons
Rectangle { // Window
id: root

View file

@ -287,4 +287,18 @@ Scope {
}
}
GlobalShortcut {
name: "sessionToggle"
description: "Toggles session screen on press"
onPressed: {
for (let i = 0; i < sessionVariants.instances.length; i++) {
let panelWindow = sessionVariants.instances[i];
if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) {
panelWindow.visible = !panelWindow.visible;
}
}
}
}
}

View file

@ -99,11 +99,21 @@ Scope {
Layout.topMargin: 5
Layout.bottomMargin: 0
// CustomIcon {
// width: 25
// height: 25
// source: SystemInfo.distroIcon
// }
Item {
implicitWidth: distroIcon.width
implicitHeight: distroIcon.height
CustomIcon {
id: distroIcon
width: 25
height: 25
source: SystemInfo.distroIcon
}
ColorOverlay {
anchors.fill: distroIcon
source: distroIcon
color: Appearance.colors.colOnLayer0
}
}
StyledText {
font.pixelSize: Appearance.font.pixelSize.normal
@ -221,4 +231,19 @@ Scope {
}
}
GlobalShortcut {
name: "sidebarRightToggle"
description: "Toggles right sidebar on press"
onPressed: {
for (let i = 0; i < sidebarVariants.instances.length; i++) {
let panelWindow = sidebarVariants.instances[i];
if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) {
panelWindow.visible = !panelWindow.visible;
if(panelWindow.visible) Notifications.timeoutAll();
}
}
}
}
}

View file

@ -16,7 +16,6 @@ import "./services/"
ShellRoot {
Component.onCompleted: {
console.log("ShellRoot loaded")
MaterialTheme.reapplyTheme()
}