controlcenter/taskbar: add excludedScreens (#1215)

also changed controlcenter/components/ConnectedButtonGroup
  - Changed row layout to grid layout
  - Added optional prop: row, which defaults to 1 so it looks same as
row layout if not given
  - added new field to options, which bypasses rootItem bind. This is
needed because we can not predict the number of monitors the user has,
and can not create a seperate variable for each one
This commit is contained in:
Bora Gülerman 2026-03-15 10:42:34 +03:00 committed by GitHub
parent d2e35a071b
commit aea2ac96ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 56 additions and 5 deletions

View file

@ -10,9 +10,10 @@ import QtQuick.Layouts
StyledRect {
id: root
property var options: [] // Array of {label: string, propertyName: string, onToggled: function}
property var options: [] // Array of {label: string, propertyName: string, onToggled: function, state: bool?}
property var rootItem: null // The root item that contains the properties we want to bind to
property string title: "" // Optional title text
property int rows: 1 // Number of rows
Layout.fillWidth: true
implicitHeight: layout.implicitHeight + Appearance.padding.large * 2
@ -37,10 +38,13 @@ StyledRect {
font.pointSize: Appearance.font.size.normal
}
RowLayout {
id: buttonRow
GridLayout {
id: buttonGrid
Layout.alignment: Qt.AlignHCenter
spacing: Appearance.spacing.small
rowSpacing: Appearance.spacing.small
columnSpacing: Appearance.spacing.small
rows: root.rows
columns: Math.ceil(root.options.length / root.rows)
Repeater {
id: repeater
@ -62,7 +66,10 @@ StyledRect {
// Create binding in Component.onCompleted
Component.onCompleted: {
if (root.rootItem && modelData.propertyName) {
if (modelData.state !== undefined && modelData.state) {
_checked = modelData.state;
}
else if (root.rootItem && modelData.propertyName) {
const propName = modelData.propertyName;
const rootItem = root.rootItem;
_checked = Qt.binding(function () {

View file

@ -46,6 +46,8 @@ Item {
property bool popoutActiveWindow: Config.bar.popouts.activeWindow ?? true
property bool popoutTray: Config.bar.popouts.tray ?? true
property bool popoutStatusIcons: Config.bar.popouts.statusIcons ?? true
property list<string> monitorNames: Hypr.monitorNames()
property list<string> excludedScreens: Config.bar.excludedScreens ?? []
anchors.fill: parent
@ -90,6 +92,7 @@ Item {
Config.bar.popouts.activeWindow = root.popoutActiveWindow;
Config.bar.popouts.tray = root.popoutTray;
Config.bar.popouts.statusIcons = root.popoutStatusIcons;
Config.bar.excludedScreens = root.excludedScreens;
const entries = [];
for (let i = 0; i < entriesModel.count; i++) {
@ -677,6 +680,43 @@ Item {
]
}
}
SectionContainer {
Layout.fillWidth: true
alignTop: true
StyledText {
text: qsTr("Monitors")
font.pointSize: Appearance.font.size.normal
}
ConnectedButtonGroup {
rootItem: root
// max 3 options per line
rows: Math.ceil(root.monitorNames.length / 3)
options: root.monitorNames.map(e => ({
label: qsTr(e),
propertyName: `monitor${e}`,
onToggled: function (_) {
// if the given monitor is in the excluded list, it should be added back
let addedBack = excludedScreens.includes(e)
if (addedBack) {
const index = excludedScreens.indexOf(e);
if (index !== -1) {
excludedScreens.splice(index, 1);
}
} else {
if (!excludedScreens.includes(e)) {
excludedScreens.push(e);
}
}
root.saveConfig();
},
state: !Strings.testRegexList(root.excludedScreens, e)
}))
}
}
}
}
}

View file

@ -75,6 +75,10 @@ Singleton {
dispatch(`workspace ${openSpecials[nextIndex].name}`);
}
function monitorNames(): list<string> {
return monitors.values.map(e => e.name);
}
function monitorFor(screen: ShellScreen): HyprlandMonitor {
return Hyprland.monitorFor(screen);
}