add noctalia and fuzzel
This commit is contained in:
+191
@@ -0,0 +1,191 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Modules.Cards
|
||||
import qs.Modules.MainScreen
|
||||
import qs.Services.Media
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
SmartPanel {
|
||||
id: root
|
||||
|
||||
// Positioning
|
||||
readonly property string controlCenterPosition: Settings.data.controlCenter.position
|
||||
|
||||
// Check if there's a bar on this screen
|
||||
readonly property bool hasBarOnScreen: {
|
||||
var monitors = Settings.data.bar.monitors || [];
|
||||
return monitors.length === 0 || monitors.includes(screen?.name);
|
||||
}
|
||||
|
||||
// When position is "close_to_bar_button" but there's no bar, fall back to center
|
||||
readonly property bool shouldCenter: controlCenterPosition === "close_to_bar_button" && !hasBarOnScreen
|
||||
|
||||
panelAnchorHorizontalCenter: shouldCenter || (controlCenterPosition !== "close_to_bar_button" && (controlCenterPosition.endsWith("_center") || controlCenterPosition === "center"))
|
||||
panelAnchorVerticalCenter: shouldCenter || controlCenterPosition === "center"
|
||||
panelAnchorLeft: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_left")
|
||||
panelAnchorRight: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_right")
|
||||
panelAnchorBottom: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("bottom_")
|
||||
panelAnchorTop: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("top_")
|
||||
|
||||
preferredWidth: Math.round(440 * Style.uiScaleRatio)
|
||||
preferredHeight: {
|
||||
var height = 0;
|
||||
var count = 0;
|
||||
for (var i = 0; i < Settings.data.controlCenter.cards.length; i++) {
|
||||
const card = Settings.data.controlCenter.cards[i];
|
||||
if (!card.enabled)
|
||||
continue;
|
||||
const contributes = (card.id !== "weather-card" || Settings.data.location.weatherEnabled);
|
||||
if (!contributes)
|
||||
continue;
|
||||
count++;
|
||||
switch (card.id) {
|
||||
case "profile-card":
|
||||
height += profileHeight;
|
||||
break;
|
||||
case "shortcuts-card":
|
||||
height += shortcutsHeight;
|
||||
break;
|
||||
case "audio-card":
|
||||
height += audioHeight;
|
||||
break;
|
||||
case "brightness-card":
|
||||
height += brightnessHeight;
|
||||
break;
|
||||
case "weather-card":
|
||||
height += weatherHeight;
|
||||
break;
|
||||
case "media-sysmon-card":
|
||||
height += mediaSysMonHeight;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return height + (count + 1) * Style.marginL;
|
||||
}
|
||||
|
||||
readonly property int profileHeight: Math.round(64 * Style.uiScaleRatio)
|
||||
readonly property int shortcutsHeight: Math.round(52 * Style.uiScaleRatio)
|
||||
readonly property int audioHeight: Math.round(60 * Style.uiScaleRatio)
|
||||
readonly property int brightnessHeight: Math.round(60 * Style.uiScaleRatio)
|
||||
readonly property int mediaSysMonHeight: Math.round(260 * Style.uiScaleRatio)
|
||||
|
||||
// We keep a dynamic weather height due to a more complex layout and font scaling
|
||||
property int weatherHeight: Math.round(210 * Style.uiScaleRatio)
|
||||
|
||||
onOpened: {
|
||||
MediaService.autoSwitchingPaused = true;
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
MediaService.autoSwitchingPaused = false;
|
||||
}
|
||||
|
||||
panelContent: Item {
|
||||
id: panelContent
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
x: Style.marginL
|
||||
y: Style.marginL
|
||||
width: parent.width - Style.margin2L
|
||||
spacing: Style.marginL
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.controlCenter.cards
|
||||
Loader {
|
||||
active: modelData.enabled && (modelData.id !== "weather-card" || Settings.data.location.weatherEnabled)
|
||||
visible: active
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: {
|
||||
switch (modelData.id) {
|
||||
case "profile-card":
|
||||
return profileHeight;
|
||||
case "shortcuts-card":
|
||||
return shortcutsHeight;
|
||||
case "audio-card":
|
||||
return audioHeight;
|
||||
case "brightness-card":
|
||||
return brightnessHeight;
|
||||
case "weather-card":
|
||||
return weatherHeight;
|
||||
case "media-sysmon-card":
|
||||
return mediaSysMonHeight;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sourceComponent: {
|
||||
switch (modelData.id) {
|
||||
case "profile-card":
|
||||
return profileCard;
|
||||
case "shortcuts-card":
|
||||
return shortcutsCard;
|
||||
case "audio-card":
|
||||
return audioCard;
|
||||
case "brightness-card":
|
||||
return brightnessCard;
|
||||
case "weather-card":
|
||||
return weatherCard;
|
||||
case "media-sysmon-card":
|
||||
return mediaSysMonCard;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: profileCard
|
||||
ProfileCard {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: shortcutsCard
|
||||
ShortcutsCard {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: audioCard
|
||||
AudioCard {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: brightnessCard
|
||||
BrightnessCard {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: weatherCard
|
||||
WeatherCard {
|
||||
Component.onCompleted: {
|
||||
root.weatherHeight = this.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mediaSysMonCard
|
||||
RowLayout {
|
||||
spacing: Style.marginL
|
||||
|
||||
// Media card
|
||||
MediaCard {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
// System monitors combined in one card
|
||||
SystemMonitorCard {
|
||||
Layout.preferredWidth: Math.round(Style.baseWidgetSize * 2.625)
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Noctalia
|
||||
import qs.Services.UI
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property string widgetId
|
||||
required property var widgetScreen
|
||||
required property var widgetProps
|
||||
|
||||
property string section: widgetProps && widgetProps.section || ""
|
||||
property int sectionIndex: widgetProps && widgetProps.sectionWidgetIndex || 0
|
||||
|
||||
// Don't reserve space unless the loaded widget is really visible
|
||||
implicitWidth: getImplicitSize(loader.item, "implicitWidth")
|
||||
implicitHeight: getImplicitSize(loader.item, "implicitHeight")
|
||||
|
||||
function getImplicitSize(item, prop) {
|
||||
return (item && item.visible) ? item[prop] : 0;
|
||||
}
|
||||
|
||||
readonly property bool _isPlugin: ControlCenterWidgetRegistry.isPluginWidget(widgetId)
|
||||
|
||||
function _loadPluginWidget() {
|
||||
var comp = ControlCenterWidgetRegistry.getWidget(widgetId);
|
||||
if (!comp)
|
||||
return;
|
||||
var pluginId = widgetId.substring(7); // Remove "plugin:" prefix
|
||||
var api = PluginService.getPluginAPI(pluginId);
|
||||
loader.setSource(comp.url, api ? {
|
||||
"pluginApi": api
|
||||
} : {});
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
asynchronous: false
|
||||
|
||||
// Core widgets use sourceComponent; plugin widgets use setSource()
|
||||
// so pluginApi is available from the first binding evaluation.
|
||||
Component.onCompleted: {
|
||||
if (root._isPlugin) {
|
||||
root._loadPluginWidget();
|
||||
} else {
|
||||
sourceComponent = Qt.binding(function () {
|
||||
return ControlCenterWidgetRegistry.getWidget(widgetId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
// Apply properties to loaded widget
|
||||
for (var prop in widgetProps) {
|
||||
if (item.hasOwnProperty(prop)) {
|
||||
item[prop] = widgetProps[prop];
|
||||
}
|
||||
}
|
||||
|
||||
// Set screen property
|
||||
if (item.hasOwnProperty("screen")) {
|
||||
item.screen = widgetScreen;
|
||||
}
|
||||
|
||||
// Call custom onLoaded if it exists
|
||||
if (item.hasOwnProperty("onLoaded")) {
|
||||
item.onLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
// Explicitly clear references
|
||||
widgetProps = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Error handling
|
||||
Component.onCompleted: {
|
||||
if (!ControlCenterWidgetRegistry.hasWidget(widgetId)) {
|
||||
Logger.w("ControlCenterWidgetLoader", "Widget not found in registry:", widgetId);
|
||||
// Retry briefly in case the registry initializes after this component
|
||||
retryTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
// Retry mechanism to cope with early evaluation before registry is ready
|
||||
Timer {
|
||||
id: retryTimer
|
||||
interval: 150
|
||||
repeat: true
|
||||
running: false
|
||||
property int attempts: 0
|
||||
onTriggered: {
|
||||
attempts += 1;
|
||||
if (ControlCenterWidgetRegistry.hasWidget(widgetId)) {
|
||||
loader.sourceComponent = ControlCenterWidgetRegistry.getWidget(widgetId);
|
||||
stop();
|
||||
attempts = 0;
|
||||
return;
|
||||
}
|
||||
if (attempts >= 20) { // ~3s max
|
||||
stop();
|
||||
attempts = 0;
|
||||
Logger.w("ControlCenterWidgetLoader", "Giving up waiting for widget:", widgetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Networking
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: !NetworkService.airplaneModeEnabled ? "plane-off" : "plane"
|
||||
hot: NetworkService.airplaneModeEnabled
|
||||
tooltipText: I18n.tr("toast.airplane-mode.title")
|
||||
onClicked: {
|
||||
NetworkService.setAirplaneMode(!NetworkService.airplaneModeEnabled);
|
||||
}
|
||||
enabled: NetworkService.wifiAvailable && BluetoothService.bluetoothAvailable
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Networking
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: !BluetoothService.enabled ? "bluetooth-off" : ((BluetoothService.connectedDevices && BluetoothService.connectedDevices.length > 0) ? "bluetooth-connected" : "bluetooth")
|
||||
tooltipText: I18n.tr("common.bluetooth")
|
||||
onClicked: {
|
||||
var p = PanelService.getPanel("bluetoothPanel", screen);
|
||||
if (p)
|
||||
p.toggle(this);
|
||||
}
|
||||
onRightClicked: {
|
||||
if (!NetworkService.airplaneModeEnabled) {
|
||||
BluetoothService.setBluetoothEnabled(!BluetoothService.enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string widgetId: "CustomButton"
|
||||
property var widgetSettings: null
|
||||
|
||||
property string onClickedCommand: ""
|
||||
property string onRightClickedCommand: ""
|
||||
property string onMiddleClickedCommand: ""
|
||||
property string stateChecksJson: "[]" // Store state checks as JSON string
|
||||
|
||||
property string generalTooltipText: ""
|
||||
property bool enableOnStateLogic: false
|
||||
property bool showExecTooltip: true
|
||||
property bool _hasCustomTooltip: false
|
||||
|
||||
property string _currentIcon: "heart" // Default icon
|
||||
property bool _isHot: false
|
||||
property var _parsedStateChecks: [] // Local array for parsed state checks
|
||||
|
||||
property int _currentStateCheckIndex: -1
|
||||
property string _activeStateIcon: ""
|
||||
|
||||
implicitWidth: button.implicitWidth
|
||||
implicitHeight: button.implicitHeight
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
|
||||
function _updatePropertiesFromSettings() {
|
||||
if (!widgetSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
onClickedCommand = widgetSettings.onClicked || "";
|
||||
onRightClickedCommand = widgetSettings.onRightClicked || "";
|
||||
onMiddleClickedCommand = widgetSettings.onMiddleClicked || "";
|
||||
stateChecksJson = widgetSettings.stateChecksJson || "[]"; // Populate from widgetSettings
|
||||
try {
|
||||
_parsedStateChecks = JSON.parse(stateChecksJson);
|
||||
} catch (e) {
|
||||
Logger.e("CustomButton", "Failed to parse stateChecksJson:", e.message);
|
||||
_parsedStateChecks = [];
|
||||
}
|
||||
generalTooltipText = widgetSettings.generalTooltipText || "";
|
||||
_hasCustomTooltip = !!(widgetSettings.generalTooltipText && widgetSettings.generalTooltipText.trim() !== "");
|
||||
enableOnStateLogic = widgetSettings.enableOnStateLogic || false;
|
||||
showExecTooltip = widgetSettings.showExecTooltip !== undefined ? widgetSettings.showExecTooltip : true;
|
||||
|
||||
updateState();
|
||||
}
|
||||
|
||||
function onWidgetSettingsChanged() {
|
||||
if (widgetSettings) {
|
||||
_updatePropertiesFromSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: stateCheckProcessExecutor
|
||||
running: false
|
||||
command: _currentStateCheckIndex !== -1 && _parsedStateChecks.length > _currentStateCheckIndex ? ["sh", "-lc", _parsedStateChecks[_currentStateCheckIndex].command] : []
|
||||
onExited: function (exitCode, stdout, stderr) {
|
||||
var currentCheckItem = _parsedStateChecks[_currentStateCheckIndex];
|
||||
var currentCommand = currentCheckItem.command;
|
||||
if (exitCode === 0) {
|
||||
// Command succeeded, this is the active state
|
||||
_isHot = true;
|
||||
_activeStateIcon = currentCheckItem.icon || widgetSettings.icon || "heart";
|
||||
} else {
|
||||
// Command failed, try next one
|
||||
_currentStateCheckIndex++;
|
||||
_checkNextState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: stateUpdateTimer
|
||||
interval: 200
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (enableOnStateLogic && _parsedStateChecks.length > 0) {
|
||||
_currentStateCheckIndex = 0;
|
||||
_checkNextState();
|
||||
} else {
|
||||
_isHot = false;
|
||||
_activeStateIcon = widgetSettings.icon || "heart";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _checkNextState() {
|
||||
if (_currentStateCheckIndex < _parsedStateChecks.length) {
|
||||
var currentCheckItem = _parsedStateChecks[_currentStateCheckIndex];
|
||||
if (currentCheckItem && currentCheckItem.command) {
|
||||
stateCheckProcessExecutor.running = true;
|
||||
} else {
|
||||
_currentStateCheckIndex++;
|
||||
_checkNextState();
|
||||
}
|
||||
} else {
|
||||
// All checks failed
|
||||
_isHot = false;
|
||||
_activeStateIcon = widgetSettings.icon || "heart";
|
||||
}
|
||||
}
|
||||
|
||||
function updateState() {
|
||||
if (!enableOnStateLogic || _parsedStateChecks.length === 0) {
|
||||
_isHot = false;
|
||||
_activeStateIcon = widgetSettings.icon || "heart";
|
||||
return;
|
||||
}
|
||||
stateUpdateTimer.restart();
|
||||
}
|
||||
|
||||
function _buildTooltipText() {
|
||||
// Build tooltip based on settings
|
||||
let tooltip = "";
|
||||
|
||||
// If user set custom text, always show it
|
||||
// If no custom text and showExecTooltip is off, show i18n default
|
||||
if (_hasCustomTooltip) {
|
||||
tooltip = generalTooltipText;
|
||||
} else if (!showExecTooltip) {
|
||||
tooltip = I18n.tr("bar.custom-button.default-tooltip");
|
||||
}
|
||||
|
||||
// Add command details if enabled
|
||||
if (showExecTooltip) {
|
||||
if (onClickedCommand) {
|
||||
tooltip += (tooltip ? "\n" : "") + I18n.tr("bar.custom-button.left-click-label") + `: ${onClickedCommand}`;
|
||||
}
|
||||
if (onRightClickedCommand) {
|
||||
tooltip += (tooltip ? "\n" : "") + I18n.tr("bar.custom-button.right-click-label") + `: ${onRightClickedCommand}`;
|
||||
}
|
||||
if (onMiddleClickedCommand) {
|
||||
tooltip += (tooltip ? "\n" : "") + I18n.tr("bar.custom-button.middle-click-label") + `: ${onMiddleClickedCommand}`;
|
||||
}
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
NIconButtonHot {
|
||||
id: button
|
||||
icon: _activeStateIcon
|
||||
hot: _isHot
|
||||
tooltipText: _buildTooltipText()
|
||||
onClicked: {
|
||||
if (onClickedCommand) {
|
||||
Quickshell.execDetached(["sh", "-lc", onClickedCommand]);
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
onRightClicked: {
|
||||
if (onRightClickedCommand) {
|
||||
Quickshell.execDetached(["sh", "-lc", onRightClickedCommand]);
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
onMiddleClicked: {
|
||||
if (onMiddleClickedCommand) {
|
||||
Quickshell.execDetached(["sh", "-lc", onMiddleClickedCommand]);
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Power
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: "dark-mode"
|
||||
tooltipText: Settings.data.colorSchemes.darkMode ? I18n.tr("tooltips.switch-to-light-mode") : I18n.tr("tooltips.switch-to-dark-mode")
|
||||
onClicked: Settings.data.colorSchemes.darkMode = !Settings.data.colorSchemes.darkMode
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Power
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
|
||||
hot: IdleInhibitorService.isInhibited
|
||||
tooltipText: I18n.tr("tooltips.keep-awake")
|
||||
onClicked: IdleInhibitorService.manualToggle()
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Networking
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
icon: NetworkService.getIcon()
|
||||
tooltipText: NetworkService.getStatusText(true)
|
||||
onClicked: {
|
||||
var panel = PanelService.getPanel("networkPanel", screen);
|
||||
panel?.toggle(this);
|
||||
}
|
||||
onRightClicked: {
|
||||
if (!NetworkService.airplaneModeEnabled) {
|
||||
NetworkService.setWifiEnabled(!NetworkService.wifiEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Modules.Panels.Settings
|
||||
import qs.Services.System
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
enabled: ProgramCheckerService.wlsunsetAvailable
|
||||
icon: Settings.data.nightLight.enabled ? (Settings.data.nightLight.forced ? "nightlight-forced" : "nightlight-on") : "nightlight-off"
|
||||
hot: Settings.data.nightLight.enabled
|
||||
tooltipText: I18n.tr("common.night-light")
|
||||
|
||||
onClicked: {
|
||||
if (!Settings.data.nightLight.enabled) {
|
||||
Settings.data.nightLight.enabled = true;
|
||||
Settings.data.nightLight.forced = false;
|
||||
} else if (Settings.data.nightLight.enabled && !Settings.data.nightLight.forced) {
|
||||
Settings.data.nightLight.forced = true;
|
||||
} else {
|
||||
Settings.data.nightLight.enabled = false;
|
||||
Settings.data.nightLight.forced = false;
|
||||
}
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel", screen);
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display;
|
||||
settingsPanel.open();
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Power
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: PowerProfileService.noctaliaPerformanceMode ? "rocket" : "rocket-off"
|
||||
tooltipText: I18n.tr("tooltips.noctalia-performance-enabled")
|
||||
hot: PowerProfileService.noctaliaPerformanceMode
|
||||
onClicked: PowerProfileService.toggleNoctaliaPerformance()
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.System
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: NotificationService.doNotDisturb ? "bell-off" : "bell"
|
||||
hot: NotificationService.doNotDisturb
|
||||
tooltipText: I18n.tr("common.notifications")
|
||||
onClicked: PanelService.getPanel("notificationHistoryPanel", screen)?.toggle(this)
|
||||
onRightClicked: NotificationService.doNotDisturb = !NotificationService.doNotDisturb
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.UPower
|
||||
import qs.Commons
|
||||
import qs.Services.Power
|
||||
import qs.Widgets
|
||||
|
||||
// Performance
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
readonly property bool hasPP: PowerProfileService.available
|
||||
|
||||
enabled: hasPP
|
||||
icon: PowerProfileService.getIcon()
|
||||
hot: !PowerProfileService.isDefault()
|
||||
tooltipText: I18n.tr("control-center.power-profile.tooltip-action")
|
||||
onClicked: PowerProfileService.cycleProfile()
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
enabled: Settings.data.wallpaper.enabled
|
||||
icon: "wallpaper-selector"
|
||||
tooltipText: I18n.tr("wallpaper.panel.title")
|
||||
onClicked: PanelService.getPanel("wallpaperPanel", screen)?.toggle()
|
||||
onRightClicked: WallpaperService.setRandomWallpaper()
|
||||
}
|
||||
Reference in New Issue
Block a user