mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-28 15:32:50 -05:00
refactor all modals and popouts so they retain animations on exit
This commit is contained in:
14
Common/ModalManager.qml
Normal file
14
Common/ModalManager.qml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import QtQuick
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: modalManager
|
||||||
|
|
||||||
|
signal closeAllModalsExcept(var excludedModal)
|
||||||
|
|
||||||
|
function openModal(modal) {
|
||||||
|
if (!modal.allowStacking) {
|
||||||
|
closeAllModalsExcept(modal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,6 @@ DankModal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
clipboardHistoryModal.totalCount = filteredClipboardModel.count;
|
clipboardHistoryModal.totalCount = filteredClipboardModel.count;
|
||||||
|
|
||||||
// Clamp selectedIndex to valid range
|
// Clamp selectedIndex to valid range
|
||||||
if (filteredClipboardModel.count === 0) {
|
if (filteredClipboardModel.count === 0) {
|
||||||
keyboardNavigationActive = false;
|
keyboardNavigationActive = false;
|
||||||
@@ -46,34 +45,35 @@ DankModal {
|
|||||||
} else if (selectedIndex >= filteredClipboardModel.count) {
|
} else if (selectedIndex >= filteredClipboardModel.count) {
|
||||||
selectedIndex = filteredClipboardModel.count - 1;
|
selectedIndex = filteredClipboardModel.count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
if (visible)
|
if (shouldBeVisible)
|
||||||
hide();
|
hide();
|
||||||
else
|
else
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
clipboardHistoryModal.visible = true;
|
open();
|
||||||
clipboardHistoryModal.searchText = "";
|
clipboardHistoryModal.searchText = "";
|
||||||
if (typeof searchField !== 'undefined' && searchField) {
|
|
||||||
searchField.text = "";
|
|
||||||
}
|
|
||||||
initializeThumbnailSystem();
|
initializeThumbnailSystem();
|
||||||
refreshClipboard();
|
refreshClipboard();
|
||||||
keyboardController.reset();
|
keyboardController.reset();
|
||||||
|
|
||||||
|
Qt.callLater(function() {
|
||||||
|
if (contentLoader.item && contentLoader.item.searchField) {
|
||||||
|
contentLoader.item.searchField.text = "";
|
||||||
|
contentLoader.item.searchField.forceActiveFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
clipboardHistoryModal.visible = false;
|
close();
|
||||||
clipboardHistoryModal.searchText = "";
|
clipboardHistoryModal.searchText = "";
|
||||||
if (typeof searchField !== 'undefined' && searchField) {
|
|
||||||
searchField.text = "";
|
|
||||||
}
|
|
||||||
updateFilteredModel();
|
updateFilteredModel();
|
||||||
keyboardController.reset();
|
keyboardController.reset();
|
||||||
cleanupTempFiles();
|
cleanupTempFiles();
|
||||||
@@ -97,7 +97,7 @@ DankModal {
|
|||||||
const entryId = entry.split('\t')[0];
|
const entryId = entry.split('\t')[0];
|
||||||
Quickshell.execDetached(["sh", "-c", `cliphist decode ${entryId} | wl-copy`]);
|
Quickshell.execDetached(["sh", "-c", `cliphist decode ${entryId} | wl-copy`]);
|
||||||
ToastService.showInfo("Copied to clipboard");
|
ToastService.showInfo("Copied to clipboard");
|
||||||
clipboardHistoryModal.hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteEntry(entry) {
|
function deleteEntry(entry) {
|
||||||
@@ -143,7 +143,6 @@ DankModal {
|
|||||||
visible: false
|
visible: false
|
||||||
width: 650
|
width: 650
|
||||||
height: 550
|
height: 550
|
||||||
keyboardFocus: "ondemand"
|
|
||||||
backgroundColor: Theme.popupBackground()
|
backgroundColor: Theme.popupBackground()
|
||||||
cornerRadius: Theme.cornerRadius
|
cornerRadius: Theme.cornerRadius
|
||||||
borderColor: Theme.outlineMedium
|
borderColor: Theme.outlineMedium
|
||||||
@@ -201,7 +200,6 @@ DankModal {
|
|||||||
deleteEntry(selectedEntry);
|
deleteEntry(selectedEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleKey(event) {
|
function handleKey(event) {
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
if (keyboardNavigationActive) {
|
if (keyboardNavigationActive) {
|
||||||
@@ -271,8 +269,7 @@ DankModal {
|
|||||||
visible: showClearConfirmation
|
visible: showClearConfirmation
|
||||||
width: 350
|
width: 350
|
||||||
height: 150
|
height: 150
|
||||||
keyboardFocus: "ondemand"
|
onBackgroundClicked: {
|
||||||
onBackgroundClicked: {
|
|
||||||
showClearConfirmation = false;
|
showClearConfirmation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +403,7 @@ DankModal {
|
|||||||
id: deleteProcess
|
id: deleteProcess
|
||||||
|
|
||||||
property string deletedEntry: ""
|
property string deletedEntry: ""
|
||||||
|
|
||||||
running: false
|
running: false
|
||||||
onExited: (exitCode) => {
|
onExited: (exitCode) => {
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
@@ -423,7 +421,6 @@ DankModal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
clipboardHistoryModal.totalCount = filteredClipboardModel.count;
|
clipboardHistoryModal.totalCount = filteredClipboardModel.count;
|
||||||
|
|
||||||
// Clamp selectedIndex to valid range
|
// Clamp selectedIndex to valid range
|
||||||
if (filteredClipboardModel.count === 0) {
|
if (filteredClipboardModel.count === 0) {
|
||||||
keyboardNavigationActive = false;
|
keyboardNavigationActive = false;
|
||||||
@@ -459,7 +456,7 @@ DankModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
clipboardHistoryModal.hide();
|
hide();
|
||||||
return "CLIPBOARD_CLOSE_SUCCESS";
|
return "CLIPBOARD_CLOSE_SUCCESS";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,6 +470,9 @@ DankModal {
|
|||||||
|
|
||||||
clipboardContent: Component {
|
clipboardContent: Component {
|
||||||
Item {
|
Item {
|
||||||
|
id: clipboardContent
|
||||||
|
property alias searchField: searchField
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -548,7 +548,7 @@ DankModal {
|
|||||||
id: searchField
|
id: searchField
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
placeholderText: "Search clipboard history..."
|
placeholderText: ""
|
||||||
leftIconName: "search"
|
leftIconName: "search"
|
||||||
showClearButton: true
|
showClearButton: true
|
||||||
focus: true
|
focus: true
|
||||||
@@ -559,7 +559,7 @@ DankModal {
|
|||||||
updateFilteredModel();
|
updateFilteredModel();
|
||||||
}
|
}
|
||||||
Keys.onEscapePressed: function(event) {
|
Keys.onEscapePressed: function(event) {
|
||||||
clipboardHistoryModal.hide();
|
hide();
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
@@ -567,6 +567,15 @@ DankModal {
|
|||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: clipboardHistoryModal
|
||||||
|
function onOpened() {
|
||||||
|
Qt.callLater(function() {
|
||||||
|
searchField.forceActiveFocus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -581,6 +590,19 @@ DankModal {
|
|||||||
DankListView {
|
DankListView {
|
||||||
id: clipboardListView
|
id: clipboardListView
|
||||||
|
|
||||||
|
function ensureVisible(index) {
|
||||||
|
if (index < 0 || index >= count)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
var itemHeight = 72 + spacing;
|
||||||
|
var itemY = index * itemHeight;
|
||||||
|
var itemBottom = itemY + itemHeight;
|
||||||
|
if (itemY < contentY)
|
||||||
|
contentY = itemY;
|
||||||
|
else if (itemBottom > contentY + height)
|
||||||
|
contentY = itemBottom - height;
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingS
|
anchors.margins: Theme.spacingS
|
||||||
clip: true
|
clip: true
|
||||||
@@ -594,27 +616,11 @@ DankModal {
|
|||||||
boundsMovement: Flickable.FollowBoundsBehavior
|
boundsMovement: Flickable.FollowBoundsBehavior
|
||||||
pressDelay: 0
|
pressDelay: 0
|
||||||
flickableDirection: Flickable.VerticalFlick
|
flickableDirection: Flickable.VerticalFlick
|
||||||
|
|
||||||
function ensureVisible(index) {
|
|
||||||
if (index < 0 || index >= count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var itemHeight = 72 + spacing;
|
|
||||||
var itemY = index * itemHeight;
|
|
||||||
var itemBottom = itemY + itemHeight;
|
|
||||||
if (itemY < contentY)
|
|
||||||
contentY = itemY;
|
|
||||||
else if (itemBottom > contentY + height)
|
|
||||||
contentY = itemBottom - height;
|
|
||||||
}
|
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
if (keyboardNavigationActive && currentIndex >= 0) {
|
if (keyboardNavigationActive && currentIndex >= 0)
|
||||||
ensureVisible(currentIndex);
|
ensureVisible(currentIndex);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "No clipboard entries found"
|
text: "No clipboard entries found"
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ PanelWindow {
|
|||||||
property real backgroundOpacity: 0.5
|
property real backgroundOpacity: 0.5
|
||||||
property string positioning: "center"
|
property string positioning: "center"
|
||||||
property point customPosition: Qt.point(0, 0)
|
property point customPosition: Qt.point(0, 0)
|
||||||
property string keyboardFocus: "ondemand"
|
|
||||||
property bool closeOnEscapeKey: true
|
property bool closeOnEscapeKey: true
|
||||||
property bool closeOnBackgroundClick: true
|
property bool closeOnBackgroundClick: true
|
||||||
property string animationType: "scale"
|
property string animationType: "scale"
|
||||||
@@ -30,36 +29,50 @@ PanelWindow {
|
|||||||
property bool enableShadow: false
|
property bool enableShadow: false
|
||||||
// Expose the focusScope for external access
|
// Expose the focusScope for external access
|
||||||
property alias modalFocusScope: focusScope
|
property alias modalFocusScope: focusScope
|
||||||
|
property bool shouldBeVisible: false
|
||||||
|
property bool shouldHaveFocus: shouldBeVisible
|
||||||
|
property bool allowFocusOverride: false
|
||||||
|
property bool allowStacking: false
|
||||||
|
|
||||||
signal opened()
|
signal opened()
|
||||||
signal dialogClosed()
|
signal dialogClosed()
|
||||||
signal backgroundClicked()
|
signal backgroundClicked()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ModalManager
|
||||||
|
function onCloseAllModalsExcept(excludedModal) {
|
||||||
|
if (excludedModal !== root && !allowStacking && shouldBeVisible) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
|
ModalManager.openModal(root)
|
||||||
|
closeTimer.stop();
|
||||||
|
shouldBeVisible = true;
|
||||||
visible = true;
|
visible = true;
|
||||||
|
focusScope.forceActiveFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
visible = false;
|
shouldBeVisible = false;
|
||||||
|
closeTimer.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
visible = !visible;
|
if (shouldBeVisible)
|
||||||
|
close();
|
||||||
|
else
|
||||||
|
open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
visible: shouldBeVisible
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
WlrLayershell.keyboardFocus: {
|
WlrLayershell.keyboardFocus: shouldHaveFocus ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||||
switch (root.keyboardFocus) {
|
|
||||||
case "exclusive":
|
|
||||||
return WlrKeyboardFocus.Exclusive;
|
|
||||||
case "none":
|
|
||||||
return WlrKeyboardFocus.None;
|
|
||||||
default:
|
|
||||||
return WlrKeyboardFocus.OnDemand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (root.visible) {
|
if (root.visible) {
|
||||||
opened();
|
opened();
|
||||||
@@ -72,6 +85,17 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: closeTimer
|
||||||
|
|
||||||
|
interval: animationDuration + 50
|
||||||
|
onTriggered: {
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: true
|
top: true
|
||||||
left: true
|
left: true
|
||||||
@@ -84,7 +108,7 @@ PanelWindow {
|
|||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "black"
|
color: "black"
|
||||||
opacity: root.showBackground ? (root.visible ? root.backgroundOpacity : 0) : 0
|
opacity: root.showBackground ? (root.shouldBeVisible ? root.backgroundOpacity : 0) : 0
|
||||||
visible: root.showBackground
|
visible: root.showBackground
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -133,10 +157,10 @@ PanelWindow {
|
|||||||
border.color: root.borderColor
|
border.color: root.borderColor
|
||||||
border.width: root.borderWidth
|
border.width: root.borderWidth
|
||||||
layer.enabled: root.enableShadow
|
layer.enabled: root.enableShadow
|
||||||
opacity: root.visible ? 1 : 0
|
opacity: root.shouldBeVisible ? 1 : 0
|
||||||
scale: {
|
scale: {
|
||||||
if (root.animationType === "scale")
|
if (root.animationType === "scale")
|
||||||
return root.visible ? 1 : 0.9;
|
return root.shouldBeVisible ? 1 : 0.9;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -145,8 +169,8 @@ PanelWindow {
|
|||||||
Translate {
|
Translate {
|
||||||
id: slideTransform
|
id: slideTransform
|
||||||
|
|
||||||
x: root.visible ? 0 : 15
|
x: root.shouldBeVisible ? 0 : 15
|
||||||
y: root.visible ? 0 : -30
|
y: root.shouldBeVisible ? 0 : -30
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
@@ -194,17 +218,29 @@ PanelWindow {
|
|||||||
visible: root.visible // Only active when the modal is visible
|
visible: root.visible // Only active when the modal is visible
|
||||||
focus: root.visible
|
focus: root.visible
|
||||||
Keys.onEscapePressed: (event) => {
|
Keys.onEscapePressed: (event) => {
|
||||||
if (root.closeOnEscapeKey) {
|
console.log("DankModal escape pressed - shouldHaveFocus:", shouldHaveFocus, "closeOnEscapeKey:", root.closeOnEscapeKey, "objectName:", root.objectName || "unnamed");
|
||||||
root.visible = false;
|
if (root.closeOnEscapeKey && shouldHaveFocus) {
|
||||||
|
console.log("DankModal handling escape");
|
||||||
|
root.close();
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible)
|
if (visible && shouldHaveFocus)
|
||||||
Qt.callLater(function() {
|
Qt.callLater(function() {
|
||||||
focusScope.forceActiveFocus();
|
focusScope.forceActiveFocus();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
function onShouldHaveFocusChanged() {
|
||||||
|
if (shouldHaveFocus && visible) {
|
||||||
|
Qt.callLater(function() {
|
||||||
|
focusScope.forceActiveFocus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import qs.Widgets
|
|||||||
|
|
||||||
DankModal {
|
DankModal {
|
||||||
id: fileBrowserModal
|
id: fileBrowserModal
|
||||||
|
objectName: "fileBrowserModal"
|
||||||
|
allowStacking: true
|
||||||
|
|
||||||
signal fileSelected(string path)
|
signal fileSelected(string path)
|
||||||
|
|
||||||
@@ -67,11 +69,10 @@ DankModal {
|
|||||||
|
|
||||||
width: 800
|
width: 800
|
||||||
height: 600
|
height: 600
|
||||||
keyboardFocus: "ondemand"
|
|
||||||
enableShadow: true
|
enableShadow: true
|
||||||
visible: false
|
visible: false
|
||||||
|
|
||||||
onBackgroundClicked: visible = false
|
onBackgroundClicked: close()
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
@@ -145,7 +146,7 @@ DankModal {
|
|||||||
iconSize: Theme.iconSize - 4
|
iconSize: Theme.iconSize - 4
|
||||||
iconColor: Theme.surfaceText
|
iconColor: Theme.surfaceText
|
||||||
hoverColor: Theme.errorHover
|
hoverColor: Theme.errorHover
|
||||||
onClicked: fileBrowserModal.visible = false
|
onClicked: fileBrowserModal.close()
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ DankModal {
|
|||||||
networkSSID = ssid
|
networkSSID = ssid
|
||||||
networkData = data
|
networkData = data
|
||||||
networkInfoModalVisible = true
|
networkInfoModalVisible = true
|
||||||
|
open()
|
||||||
NetworkService.fetchNetworkInfo(ssid)
|
NetworkService.fetchNetworkInfo(ssid)
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideDialog() {
|
function hideDialog() {
|
||||||
networkInfoModalVisible = false
|
networkInfoModalVisible = false
|
||||||
|
close()
|
||||||
networkSSID = ""
|
networkSSID = ""
|
||||||
networkData = null
|
networkData = null
|
||||||
networkDetails = ""
|
networkDetails = ""
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ DankModal {
|
|||||||
width: 500
|
width: 500
|
||||||
height: 700
|
height: 700
|
||||||
visible: false
|
visible: false
|
||||||
keyboardFocus: "ondemand"
|
|
||||||
onBackgroundClicked: hide()
|
onBackgroundClicked: hide()
|
||||||
onDialogClosed: {
|
onDialogClosed: {
|
||||||
notificationModalOpen = false
|
notificationModalOpen = false
|
||||||
@@ -40,7 +39,7 @@ DankModal {
|
|||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
notificationModalOpen = true
|
notificationModalOpen = true
|
||||||
visible = true
|
open()
|
||||||
modalKeyboardController.reset()
|
modalKeyboardController.reset()
|
||||||
|
|
||||||
if (modalKeyboardController && notificationListRef) {
|
if (modalKeyboardController && notificationListRef) {
|
||||||
@@ -51,12 +50,12 @@ DankModal {
|
|||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
notificationModalOpen = false
|
notificationModalOpen = false
|
||||||
visible = false
|
close()
|
||||||
modalKeyboardController.reset()
|
modalKeyboardController.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
if (notificationModalOpen)
|
if (shouldBeVisible)
|
||||||
hide()
|
hide()
|
||||||
else
|
else
|
||||||
show()
|
show()
|
||||||
|
|||||||
@@ -9,11 +9,17 @@ import qs.Widgets
|
|||||||
DankModal {
|
DankModal {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool powerConfirmVisible: false
|
|
||||||
property string powerConfirmAction: ""
|
property string powerConfirmAction: ""
|
||||||
property string powerConfirmTitle: ""
|
property string powerConfirmTitle: ""
|
||||||
property string powerConfirmMessage: ""
|
property string powerConfirmMessage: ""
|
||||||
|
|
||||||
|
function show(action, title, message) {
|
||||||
|
powerConfirmAction = action
|
||||||
|
powerConfirmTitle = title
|
||||||
|
powerConfirmMessage = message
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
|
||||||
function executePowerAction(action) {
|
function executePowerAction(action) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "logout":
|
case "logout":
|
||||||
@@ -31,13 +37,12 @@ DankModal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: powerConfirmVisible
|
shouldBeVisible: false
|
||||||
width: 350
|
width: 350
|
||||||
height: 160
|
height: 160
|
||||||
keyboardFocus: "ondemand"
|
|
||||||
enableShadow: false
|
enableShadow: false
|
||||||
onBackgroundClicked: {
|
onBackgroundClicked: {
|
||||||
powerConfirmVisible = false
|
close()
|
||||||
}
|
}
|
||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
@@ -105,7 +110,7 @@ DankModal {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
powerConfirmVisible = false
|
close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +153,7 @@ DankModal {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
powerConfirmVisible = false
|
close()
|
||||||
executePowerAction(powerConfirmAction)
|
executePowerAction(powerConfirmAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,324 +12,353 @@ import qs.Services
|
|||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
DankModal {
|
DankModal {
|
||||||
id: processListModal
|
id: processListModal
|
||||||
|
|
||||||
property int currentTab: 0
|
property int currentTab: 0
|
||||||
property var tabNames: ["Processes", "Performance", "System"]
|
property var tabNames: ["Processes", "Performance", "System"]
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
if (!DgopService.dgopAvailable) {
|
if (!DgopService.dgopAvailable) {
|
||||||
console.warn("ProcessListModal: dgop is not available")
|
console.warn("ProcessListModal: dgop is not available");
|
||||||
return
|
return ;
|
||||||
}
|
|
||||||
processListModal.visible = true
|
|
||||||
UserInfoService.getUptime()
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
processListModal.visible = false
|
|
||||||
if (processContextMenu.visible)
|
|
||||||
processContextMenu.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
if (!DgopService.dgopAvailable) {
|
|
||||||
console.warn("ProcessListModal: dgop is not available")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (processListModal.visible)
|
|
||||||
hide()
|
|
||||||
else
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 900
|
|
||||||
height: 680
|
|
||||||
visible: false
|
|
||||||
keyboardFocus: "exclusive"
|
|
||||||
backgroundColor: Theme.popupBackground()
|
|
||||||
cornerRadius: Theme.cornerRadius
|
|
||||||
enableShadow: true
|
|
||||||
onBackgroundClicked: hide()
|
|
||||||
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: processesTabComponent
|
|
||||||
|
|
||||||
ProcessesTab {
|
|
||||||
contextMenu: processContextMenu
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: performanceTabComponent
|
|
||||||
|
|
||||||
PerformanceTab {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: systemTabComponent
|
|
||||||
|
|
||||||
SystemTab {}
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessContextMenu {
|
|
||||||
id: processContextMenu
|
|
||||||
}
|
|
||||||
|
|
||||||
content: Component {
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
focus: true
|
|
||||||
Keys.onPressed: function (event) {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
processListModal.hide()
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_1) {
|
|
||||||
currentTab = 0
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_2) {
|
|
||||||
currentTab = 1
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_3) {
|
|
||||||
currentTab = 2
|
|
||||||
event.accepted = true
|
|
||||||
}
|
}
|
||||||
}
|
open();
|
||||||
|
UserInfoService.getUptime();
|
||||||
|
}
|
||||||
|
|
||||||
// Show error message when dgop is not available
|
function hide() {
|
||||||
Rectangle {
|
close();
|
||||||
anchors.centerIn: parent
|
if (processContextMenu.visible)
|
||||||
width: 400
|
processContextMenu.close();
|
||||||
height: 200
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.1)
|
|
||||||
border.color: Theme.error
|
|
||||||
border.width: 2
|
|
||||||
visible: !DgopService.dgopAvailable
|
|
||||||
|
|
||||||
Column {
|
}
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingL
|
|
||||||
|
|
||||||
DankIcon {
|
function toggle() {
|
||||||
name: "error"
|
if (!DgopService.dgopAvailable) {
|
||||||
size: 48
|
console.warn("ProcessListModal: dgop is not available");
|
||||||
color: Theme.error
|
return ;
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "System Monitor Unavailable"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Bold
|
|
||||||
color: Theme.error
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "The 'dgop' tool is required for system monitoring.\nPlease install dgop to use this feature."
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if (shouldBeVisible)
|
||||||
|
hide();
|
||||||
|
else
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
width: 900
|
||||||
anchors.fill: parent
|
height: 680
|
||||||
anchors.margins: Theme.spacingL
|
visible: false
|
||||||
spacing: Theme.spacingL
|
backgroundColor: Theme.popupBackground()
|
||||||
visible: DgopService.dgopAvailable
|
cornerRadius: Theme.cornerRadius
|
||||||
|
enableShadow: true
|
||||||
|
onBackgroundClicked: hide()
|
||||||
|
|
||||||
RowLayout {
|
Component {
|
||||||
Layout.fillWidth: true
|
id: processesTabComponent
|
||||||
height: 40
|
|
||||||
|
|
||||||
StyledText {
|
ProcessesTab {
|
||||||
text: "System Monitor"
|
contextMenu: processContextMenu
|
||||||
font.pixelSize: Theme.fontSizeLarge + 4
|
|
||||||
font.weight: Font.Bold
|
|
||||||
color: Theme.surfaceText
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
circular: false
|
|
||||||
iconName: "close"
|
|
||||||
iconSize: Theme.iconSize - 4
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
hoverColor: Theme.errorHover
|
|
||||||
onClicked: processListModal.hide()
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
}
|
||||||
Layout.fillWidth: true
|
|
||||||
height: 52
|
|
||||||
color: Theme.surfaceSelected
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
border.color: Theme.outlineLight
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Row {
|
Component {
|
||||||
|
id: performanceTabComponent
|
||||||
|
|
||||||
|
PerformanceTab {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: systemTabComponent
|
||||||
|
|
||||||
|
SystemTab {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessContextMenu {
|
||||||
|
id: processContextMenu
|
||||||
|
}
|
||||||
|
|
||||||
|
content: Component {
|
||||||
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 4
|
focus: true
|
||||||
spacing: 2
|
Keys.onPressed: function(event) {
|
||||||
|
if (event.key === Qt.Key_Escape) {
|
||||||
|
processListModal.hide();
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_1) {
|
||||||
|
currentTab = 0;
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_2) {
|
||||||
|
currentTab = 1;
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_3) {
|
||||||
|
currentTab = 2;
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
// Show error message when dgop is not available
|
||||||
model: tabNames
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
Rectangle {
|
width: 400
|
||||||
width: (parent.width - (tabNames.length - 1) * 2) / tabNames.length
|
height: 200
|
||||||
height: 44
|
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: currentTab === index ? Theme.primaryPressed : (tabMouseArea.containsMouse ? Theme.primaryHoverLight : "transparent")
|
color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.1)
|
||||||
border.color: currentTab === index ? Theme.primary : "transparent"
|
border.color: Theme.error
|
||||||
border.width: currentTab === index ? 1 : 0
|
border.width: 2
|
||||||
|
visible: !DgopService.dgopAvailable
|
||||||
|
|
||||||
Row {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: {
|
name: "error"
|
||||||
switch (index) {
|
size: 48
|
||||||
case 0:
|
color: Theme.error
|
||||||
return "list_alt"
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
case 1:
|
|
||||||
return "analytics"
|
|
||||||
case 2:
|
|
||||||
return "settings"
|
|
||||||
default:
|
|
||||||
return "tab"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: currentTab === index ? Theme.primary : Theme.surfaceText
|
|
||||||
opacity: currentTab === index ? 1 : 0.7
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
Behavior on color {
|
StyledText {
|
||||||
ColorAnimation {
|
text: "System Monitor Unavailable"
|
||||||
duration: Theme.shortDuration
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
}
|
font.weight: Font.Bold
|
||||||
|
color: Theme.error
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: modelData
|
text: "The 'dgop' tool is required for system monitoring.\nPlease install dgop to use this feature."
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.weight: Font.Medium
|
color: Theme.surfaceText
|
||||||
color: currentTab === index ? Theme.primary : Theme.surfaceText
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
anchors.verticalCenterOffset: -1
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: tabMouseArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
currentTab = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on border.color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
visible: DgopService.dgopAvailable
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "System Monitor"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge + 4
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
circular: false
|
||||||
|
iconName: "close"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
hoverColor: Theme.errorHover
|
||||||
|
onClicked: processListModal.hide()
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 52
|
||||||
|
color: Theme.surfaceSelected
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
border.color: Theme.outlineLight
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 4
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: tabNames
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: (parent.width - (tabNames.length - 1) * 2) / tabNames.length
|
||||||
|
height: 44
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: currentTab === index ? Theme.primaryPressed : (tabMouseArea.containsMouse ? Theme.primaryHoverLight : "transparent")
|
||||||
|
border.color: currentTab === index ? Theme.primary : "transparent"
|
||||||
|
border.width: currentTab === index ? 1 : 0
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return "list_alt";
|
||||||
|
case 1:
|
||||||
|
return "analytics";
|
||||||
|
case 2:
|
||||||
|
return "settings";
|
||||||
|
default:
|
||||||
|
return "tab";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size: Theme.iconSize - 2
|
||||||
|
color: currentTab === index ? Theme.primary : Theme.surfaceText
|
||||||
|
opacity: currentTab === index ? 1 : 0.7
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: currentTab === index ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.verticalCenterOffset: -1
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: tabMouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
currentTab = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.surfaceLight
|
||||||
|
border.color: Theme.outlineLight
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: processesTab
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingS
|
||||||
|
active: processListModal.visible && currentTab === 0
|
||||||
|
visible: currentTab === 0
|
||||||
|
opacity: currentTab === 0 ? 1 : 0
|
||||||
|
sourceComponent: processesTabComponent
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: performanceTab
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingS
|
||||||
|
active: processListModal.visible && currentTab === 1
|
||||||
|
visible: currentTab === 1
|
||||||
|
opacity: currentTab === 1 ? 1 : 0
|
||||||
|
sourceComponent: performanceTabComponent
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: systemTab
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingS
|
||||||
|
active: processListModal.visible && currentTab === 2
|
||||||
|
visible: currentTab === 2
|
||||||
|
opacity: currentTab === 2 ? 1 : 0
|
||||||
|
sourceComponent: systemTabComponent
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Theme.surfaceLight
|
|
||||||
border.color: Theme.outlineLight
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: processesTab
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingS
|
|
||||||
active: processListModal.visible && currentTab === 0
|
|
||||||
visible: currentTab === 0
|
|
||||||
opacity: currentTab === 0 ? 1 : 0
|
|
||||||
sourceComponent: processesTabComponent
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: performanceTab
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingS
|
|
||||||
active: processListModal.visible && currentTab === 1
|
|
||||||
visible: currentTab === 1
|
|
||||||
opacity: currentTab === 1 ? 1 : 0
|
|
||||||
sourceComponent: performanceTabComponent
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: systemTab
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingS
|
|
||||||
active: processListModal.visible && currentTab === 2
|
|
||||||
visible: currentTab === 2
|
|
||||||
opacity: currentTab === 2 ? 1 : 0
|
|
||||||
sourceComponent: systemTabComponent
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,19 +10,20 @@ import qs.Widgets
|
|||||||
|
|
||||||
DankModal {
|
DankModal {
|
||||||
id: settingsModal
|
id: settingsModal
|
||||||
|
objectName: "settingsModal"
|
||||||
|
|
||||||
signal closingModal
|
signal closingModal
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
settingsModal.visible = true
|
open()
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
settingsModal.visible = false
|
close()
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
if (settingsModal.visible)
|
if (shouldBeVisible)
|
||||||
hide()
|
hide()
|
||||||
else
|
else
|
||||||
show()
|
show()
|
||||||
@@ -31,19 +32,12 @@ DankModal {
|
|||||||
width: 750
|
width: 750
|
||||||
height: 750
|
height: 750
|
||||||
visible: false
|
visible: false
|
||||||
keyboardFocus: "ondemand"
|
|
||||||
onBackgroundClicked: hide()
|
onBackgroundClicked: hide()
|
||||||
|
|
||||||
property Component settingsContent: Component {
|
property Component settingsContent: Component {
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
Keys.onPressed: function (event) {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
settingsModal.hide()
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -128,7 +122,9 @@ DankModal {
|
|||||||
visible: active
|
visible: active
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
PersonalizationTab {}
|
PersonalizationTab {
|
||||||
|
parentModal: settingsModal
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,92 @@ DankModal {
|
|||||||
property bool spotlightOpen: false
|
property bool spotlightOpen: false
|
||||||
property Component spotlightContent
|
property Component spotlightContent
|
||||||
|
|
||||||
|
function show() {
|
||||||
|
spotlightOpen = true;
|
||||||
|
open();
|
||||||
|
if (contentLoader.item && contentLoader.item.appLauncher)
|
||||||
|
contentLoader.item.appLauncher.searchQuery = "";
|
||||||
|
|
||||||
|
Qt.callLater(function() {
|
||||||
|
if (contentLoader.item && contentLoader.item.searchField)
|
||||||
|
contentLoader.item.searchField.forceActiveFocus();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hide() {
|
||||||
|
spotlightOpen = false;
|
||||||
|
close();
|
||||||
|
if (contentLoader.item && contentLoader.item.appLauncher) {
|
||||||
|
contentLoader.item.appLauncher.searchQuery = "";
|
||||||
|
contentLoader.item.appLauncher.selectedIndex = 0;
|
||||||
|
contentLoader.item.appLauncher.setCategory("All");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if (spotlightOpen)
|
||||||
|
hide();
|
||||||
|
else
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldBeVisible: spotlightOpen
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ModalManager
|
||||||
|
function onCloseAllModalsExcept(excludedModal) {
|
||||||
|
if (excludedModal !== spotlightModal && !allowStacking && spotlightOpen) {
|
||||||
|
spotlightOpen = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width: 550
|
||||||
|
height: 600
|
||||||
|
backgroundColor: Theme.popupBackground()
|
||||||
|
cornerRadius: Theme.cornerRadius
|
||||||
|
borderColor: Theme.outlineMedium
|
||||||
|
borderWidth: 1
|
||||||
|
enableShadow: true
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible && !spotlightOpen)
|
||||||
|
show();
|
||||||
|
|
||||||
|
if (visible && contentLoader.item)
|
||||||
|
Qt.callLater(function() {
|
||||||
|
if (contentLoader.item.searchField)
|
||||||
|
contentLoader.item.searchField.forceActiveFocus();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
onBackgroundClicked: {
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
}
|
||||||
|
content: spotlightContent
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
function open() {
|
||||||
|
spotlightModal.show();
|
||||||
|
return "SPOTLIGHT_OPEN_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
spotlightModal.hide();
|
||||||
|
return "SPOTLIGHT_CLOSE_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
spotlightModal.toggle();
|
||||||
|
return "SPOTLIGHT_TOGGLE_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
target: "spotlight"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
spotlightContent: Component {
|
spotlightContent: Component {
|
||||||
Item {
|
Item {
|
||||||
id: spotlightKeyHandler
|
id: spotlightKeyHandler
|
||||||
@@ -111,7 +197,7 @@ DankModal {
|
|||||||
textColor: Theme.surfaceText
|
textColor: Theme.surfaceText
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
enabled: spotlightOpen
|
enabled: spotlightOpen
|
||||||
placeholderText: "Search applications..."
|
placeholderText: ""
|
||||||
ignoreLeftRightKeys: true
|
ignoreLeftRightKeys: true
|
||||||
keyForwardTargets: [spotlightKeyHandler]
|
keyForwardTargets: [spotlightKeyHandler]
|
||||||
text: appLauncher.searchQuery
|
text: appLauncher.searchQuery
|
||||||
@@ -132,8 +218,6 @@ DankModal {
|
|||||||
event.accepted = false;
|
event.accepted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -357,6 +441,7 @@ DankModal {
|
|||||||
onEntered: {
|
onEntered: {
|
||||||
if (resultsList.hoverUpdatesSelection && !resultsList.keyboardNavigationActive)
|
if (resultsList.hoverUpdatesSelection && !resultsList.keyboardNavigationActive)
|
||||||
resultsList.currentIndex = index;
|
resultsList.currentIndex = index;
|
||||||
|
|
||||||
}
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
resultsList.keyboardNavigationReset();
|
resultsList.keyboardNavigationReset();
|
||||||
@@ -365,8 +450,8 @@ DankModal {
|
|||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
resultsList.itemClicked(index, model);
|
resultsList.itemClicked(index, model);
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
var globalPos = mapToGlobal(mouse.x, mouse.y);
|
var modalPos = mapToItem(spotlightKeyHandler, mouse.x, mouse.y);
|
||||||
resultsList.itemRightClicked(index, model, globalPos.x, globalPos.y);
|
resultsList.itemRightClicked(index, model, modalPos.x, modalPos.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -521,6 +606,7 @@ DankModal {
|
|||||||
onEntered: {
|
onEntered: {
|
||||||
if (resultsGrid.hoverUpdatesSelection && !resultsGrid.keyboardNavigationActive)
|
if (resultsGrid.hoverUpdatesSelection && !resultsGrid.keyboardNavigationActive)
|
||||||
resultsGrid.currentIndex = index;
|
resultsGrid.currentIndex = index;
|
||||||
|
|
||||||
}
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
resultsGrid.keyboardNavigationReset();
|
resultsGrid.keyboardNavigationReset();
|
||||||
@@ -529,8 +615,8 @@ DankModal {
|
|||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
resultsGrid.itemClicked(index, model);
|
resultsGrid.itemClicked(index, model);
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
var globalPos = mapToGlobal(mouse.x, mouse.y);
|
var modalPos = mapToItem(spotlightKeyHandler, mouse.x, mouse.y);
|
||||||
resultsGrid.itemRightClicked(index, model, globalPos.x, globalPos.y);
|
resultsGrid.itemRightClicked(index, model, modalPos.x, modalPos.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -543,274 +629,225 @@ DankModal {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
Rectangle {
|
||||||
|
id: contextMenu
|
||||||
|
|
||||||
}
|
property var currentApp: null
|
||||||
|
property bool menuVisible: false
|
||||||
function show() {
|
|
||||||
spotlightOpen = true;
|
|
||||||
if (contentLoader.item && contentLoader.item.appLauncher)
|
|
||||||
contentLoader.item.appLauncher.searchQuery = "";
|
|
||||||
|
|
||||||
Qt.callLater(function() {
|
|
||||||
if (contentLoader.item && contentLoader.item.searchField) {
|
|
||||||
contentLoader.item.searchField.forceActiveFocus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
spotlightOpen = false;
|
|
||||||
if (contentLoader.item && contentLoader.item.appLauncher) {
|
|
||||||
contentLoader.item.appLauncher.searchQuery = "";
|
|
||||||
contentLoader.item.appLauncher.selectedIndex = 0;
|
|
||||||
contentLoader.item.appLauncher.setCategory("All");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
if (spotlightOpen)
|
|
||||||
hide();
|
|
||||||
else
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
visible: spotlightOpen
|
|
||||||
width: 550
|
|
||||||
height: 600
|
|
||||||
keyboardFocus: "ondemand"
|
|
||||||
backgroundColor: Theme.popupBackground()
|
|
||||||
cornerRadius: Theme.cornerRadius
|
|
||||||
borderColor: Theme.outlineMedium
|
|
||||||
borderWidth: 1
|
|
||||||
enableShadow: true
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible && !spotlightOpen)
|
|
||||||
show();
|
|
||||||
|
|
||||||
if (visible && contentLoader.item) {
|
|
||||||
Qt.callLater(function() {
|
|
||||||
if (contentLoader.item.searchField) {
|
|
||||||
contentLoader.item.searchField.forceActiveFocus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBackgroundClicked: {
|
|
||||||
spotlightOpen = false;
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
}
|
|
||||||
content: spotlightContent
|
|
||||||
IpcHandler {
|
|
||||||
function open() {
|
|
||||||
spotlightModal.show();
|
|
||||||
return "SPOTLIGHT_OPEN_SUCCESS";
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
spotlightModal.hide();
|
|
||||||
return "SPOTLIGHT_CLOSE_SUCCESS";
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
spotlightModal.toggle();
|
|
||||||
return "SPOTLIGHT_TOGGLE_SUCCESS";
|
|
||||||
}
|
|
||||||
|
|
||||||
target: "spotlight"
|
|
||||||
}
|
|
||||||
|
|
||||||
Popup {
|
|
||||||
id: contextMenu
|
|
||||||
|
|
||||||
property var currentApp: null
|
|
||||||
|
|
||||||
function show(x, y, app) {
|
|
||||||
currentApp = app;
|
|
||||||
if (!contextMenu.parent && typeof Overlay !== "undefined" && Overlay.overlay)
|
|
||||||
contextMenu.parent = Overlay.overlay;
|
|
||||||
|
|
||||||
const menuWidth = 180;
|
|
||||||
const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2;
|
|
||||||
const screenWidth = Screen.width;
|
|
||||||
const screenHeight = Screen.height;
|
|
||||||
let finalX = x;
|
|
||||||
let finalY = y;
|
|
||||||
if (x + menuWidth > screenWidth - 20)
|
|
||||||
finalX = x - menuWidth;
|
|
||||||
|
|
||||||
if (y + menuHeight > screenHeight - 20)
|
|
||||||
finalY = y - menuHeight;
|
|
||||||
|
|
||||||
contextMenu.x = Math.max(20, finalX);
|
|
||||||
contextMenu.y = Math.max(20, finalY);
|
|
||||||
open();
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 180
|
|
||||||
height: menuColumn.implicitHeight + Theme.spacingS * 2
|
|
||||||
padding: 0
|
|
||||||
modal: false
|
|
||||||
closePolicy: Popup.CloseOnEscape
|
|
||||||
onClosed: {
|
|
||||||
closePolicy = Popup.CloseOnEscape;
|
|
||||||
}
|
|
||||||
onOpened: {
|
|
||||||
outsideClickTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: outsideClickTimer
|
|
||||||
|
|
||||||
interval: 100
|
|
||||||
onTriggered: {
|
|
||||||
contextMenu.closePolicy = Popup.CloseOnEscape | Popup.CloseOnPressOutside;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Rectangle {
|
|
||||||
color: Theme.popupBackground()
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: menuColumn
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingS
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: 32
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: pinMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: {
|
|
||||||
if (!contextMenu.currentApp || !contextMenu.currentApp.desktopEntry)
|
|
||||||
return "push_pin";
|
|
||||||
|
|
||||||
var appId = contextMenu.currentApp.desktopEntry.id || contextMenu.currentApp.desktopEntry.execString || "";
|
|
||||||
return SessionData.isPinnedApp(appId) ? "keep_off" : "push_pin";
|
|
||||||
}
|
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: Theme.surfaceText
|
|
||||||
opacity: 0.7
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (!contextMenu.currentApp || !contextMenu.currentApp.desktopEntry)
|
|
||||||
return "Pin to Dock";
|
|
||||||
|
|
||||||
var appId = contextMenu.currentApp.desktopEntry.id || contextMenu.currentApp.desktopEntry.execString || "";
|
|
||||||
return SessionData.isPinnedApp(appId) ? "Unpin from Dock" : "Pin to Dock";
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function show(x, y, app) {
|
||||||
|
currentApp = app
|
||||||
|
|
||||||
|
const menuWidth = 180
|
||||||
|
const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2
|
||||||
|
let finalX = x + 8
|
||||||
|
let finalY = y + 8
|
||||||
|
|
||||||
|
if (finalX + menuWidth > spotlightKeyHandler.width) {
|
||||||
|
finalX = x - menuWidth - 8
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
if (finalY + menuHeight > spotlightKeyHandler.height) {
|
||||||
id: pinMouseArea
|
finalY = y - menuHeight - 8
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
if (!contextMenu.currentApp || !contextMenu.currentApp.desktopEntry)
|
|
||||||
return ;
|
|
||||||
|
|
||||||
var appId = contextMenu.currentApp.desktopEntry.id || contextMenu.currentApp.desktopEntry.execString || "";
|
|
||||||
if (SessionData.isPinnedApp(appId))
|
|
||||||
SessionData.removePinnedApp(appId);
|
|
||||||
else
|
|
||||||
SessionData.addPinnedApp(appId);
|
|
||||||
contextMenu.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalX = Math.max(8, Math.min(finalX, spotlightKeyHandler.width - menuWidth - 8))
|
||||||
|
finalY = Math.max(8, Math.min(finalY, spotlightKeyHandler.height - menuHeight - 8))
|
||||||
|
|
||||||
|
contextMenu.x = finalX
|
||||||
|
contextMenu.y = finalY
|
||||||
|
contextMenu.visible = true
|
||||||
|
contextMenu.menuVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
contextMenu.menuVisible = false
|
||||||
|
Qt.callLater(() => {
|
||||||
|
contextMenu.visible = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
width: 180
|
||||||
|
height: menuColumn.implicitHeight + Theme.spacingS * 2
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.popupBackground()
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
|
border.width: 1
|
||||||
|
z: 1000
|
||||||
|
opacity: menuVisible ? 1 : 0
|
||||||
|
scale: menuVisible ? 1 : 0.85
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width - Theme.spacingS * 2
|
anchors.fill: parent
|
||||||
height: 5
|
anchors.topMargin: 4
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.leftMargin: 2
|
||||||
color: "transparent"
|
anchors.rightMargin: -2
|
||||||
|
anchors.bottomMargin: -4
|
||||||
|
radius: parent.radius
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.15)
|
||||||
|
z: parent.z - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: menuColumn
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingS
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 32
|
||||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
radius: Theme.cornerRadius
|
||||||
|
color: pinMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: {
|
||||||
|
if (!contextMenu.currentApp || !contextMenu.currentApp.desktopEntry)
|
||||||
|
return "push_pin"
|
||||||
|
|
||||||
|
var appId = contextMenu.currentApp.desktopEntry.id || contextMenu.currentApp.desktopEntry.execString || ""
|
||||||
|
return SessionData.isPinnedApp(appId) ? "keep_off" : "push_pin"
|
||||||
|
}
|
||||||
|
size: Theme.iconSize - 2
|
||||||
|
color: Theme.surfaceText
|
||||||
|
opacity: 0.7
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (!contextMenu.currentApp || !contextMenu.currentApp.desktopEntry)
|
||||||
|
return "Pin to Dock"
|
||||||
|
|
||||||
|
var appId = contextMenu.currentApp.desktopEntry.id || contextMenu.currentApp.desktopEntry.execString || ""
|
||||||
|
return SessionData.isPinnedApp(appId) ? "Unpin from Dock" : "Pin to Dock"
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: pinMouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (!contextMenu.currentApp || !contextMenu.currentApp.desktopEntry)
|
||||||
|
return
|
||||||
|
|
||||||
|
var appId = contextMenu.currentApp.desktopEntry.id || contextMenu.currentApp.desktopEntry.execString || ""
|
||||||
|
if (SessionData.isPinnedApp(appId))
|
||||||
|
SessionData.removePinnedApp(appId)
|
||||||
|
else
|
||||||
|
SessionData.addPinnedApp(appId)
|
||||||
|
contextMenu.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width - Theme.spacingS * 2
|
||||||
|
height: 5
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 32
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: launchMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "launch"
|
||||||
|
size: Theme.iconSize - 2
|
||||||
|
color: Theme.surfaceText
|
||||||
|
opacity: 0.7
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Launch"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: launchMouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (contextMenu.currentApp)
|
||||||
|
appLauncher.launchApp(contextMenu.currentApp)
|
||||||
|
|
||||||
|
contextMenu.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Behavior on opacity {
|
||||||
width: parent.width
|
NumberAnimation {
|
||||||
height: 32
|
duration: Theme.mediumDuration
|
||||||
radius: Theme.cornerRadius
|
easing.type: Theme.emphasizedEasing
|
||||||
color: launchMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "launch"
|
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: Theme.surfaceText
|
|
||||||
opacity: 0.7
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Launch"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: launchMouseArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
if (contextMenu.currentApp && contentLoader.item && contentLoader.item.appLauncher)
|
|
||||||
contentLoader.item.appLauncher.launchApp(contextMenu.currentApp);
|
|
||||||
|
|
||||||
contextMenu.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: contextMenu.visible
|
||||||
|
z: 999
|
||||||
|
onClicked: {
|
||||||
|
contextMenu.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
x: contextMenu.x
|
||||||
|
y: contextMenu.y
|
||||||
|
width: contextMenu.width
|
||||||
|
height: contextMenu.height
|
||||||
|
onClicked: {
|
||||||
|
// Prevent closing when clicking on the menu itself
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,20 +7,36 @@ import qs.Widgets
|
|||||||
DankModal {
|
DankModal {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool wifiPasswordModalVisible: false
|
|
||||||
property string wifiPasswordSSID: ""
|
property string wifiPasswordSSID: ""
|
||||||
property string wifiPasswordInput: ""
|
property string wifiPasswordInput: ""
|
||||||
|
|
||||||
visible: wifiPasswordModalVisible
|
function show(ssid) {
|
||||||
|
wifiPasswordSSID = ssid
|
||||||
|
wifiPasswordInput = ""
|
||||||
|
open()
|
||||||
|
Qt.callLater(function() {
|
||||||
|
if (contentLoader.item && contentLoader.item.passwordInput) {
|
||||||
|
contentLoader.item.passwordInput.forceActiveFocus()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldBeVisible: false
|
||||||
width: 420
|
width: 420
|
||||||
height: 230
|
height: 230
|
||||||
keyboardFocus: "exclusive"
|
onShouldBeVisibleChanged: {
|
||||||
onVisibleChanged: {
|
if (!shouldBeVisible)
|
||||||
if (!visible)
|
|
||||||
wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
}
|
}
|
||||||
|
onOpened: {
|
||||||
|
Qt.callLater(function() {
|
||||||
|
if (contentLoader.item && contentLoader.item.passwordInput) {
|
||||||
|
contentLoader.item.passwordInput.forceActiveFocus()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
onBackgroundClicked: {
|
onBackgroundClicked: {
|
||||||
wifiPasswordModalVisible = false
|
close()
|
||||||
wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +46,7 @@ DankModal {
|
|||||||
&& NetworkService.connectingSSID !== "") {
|
&& NetworkService.connectingSSID !== "") {
|
||||||
wifiPasswordSSID = NetworkService.connectingSSID
|
wifiPasswordSSID = NetworkService.connectingSSID
|
||||||
wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
wifiPasswordModalVisible = true
|
open()
|
||||||
NetworkService.passwordDialogShouldReopen = false
|
NetworkService.passwordDialogShouldReopen = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,8 +56,16 @@ DankModal {
|
|||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
FocusScope {
|
FocusScope {
|
||||||
|
id: wifiContent
|
||||||
|
property alias passwordInput: passwordInput
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
|
Keys.onEscapePressed: function(event) {
|
||||||
|
close()
|
||||||
|
wifiPasswordInput = ""
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -77,7 +101,7 @@ DankModal {
|
|||||||
iconColor: Theme.surfaceText
|
iconColor: Theme.surfaceText
|
||||||
hoverColor: Theme.errorHover
|
hoverColor: Theme.errorHover
|
||||||
onClicked: {
|
onClicked: {
|
||||||
wifiPasswordModalVisible = false
|
close()
|
||||||
wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,6 +115,13 @@ DankModal {
|
|||||||
border.color: passwordInput.activeFocus ? Theme.primary : Theme.outlineStrong
|
border.color: passwordInput.activeFocus ? Theme.primary : Theme.outlineStrong
|
||||||
border.width: passwordInput.activeFocus ? 2 : 1
|
border.width: passwordInput.activeFocus ? 2 : 1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
passwordInput.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DankTextField {
|
DankTextField {
|
||||||
id: passwordInput
|
id: passwordInput
|
||||||
|
|
||||||
@@ -99,42 +130,45 @@ DankModal {
|
|||||||
textColor: Theme.surfaceText
|
textColor: Theme.surfaceText
|
||||||
text: wifiPasswordInput
|
text: wifiPasswordInput
|
||||||
echoMode: showPasswordCheckbox.checked ? TextInput.Normal : TextInput.Password
|
echoMode: showPasswordCheckbox.checked ? TextInput.Normal : TextInput.Password
|
||||||
placeholderText: "Enter password"
|
placeholderText: ""
|
||||||
backgroundColor: "transparent"
|
backgroundColor: "transparent"
|
||||||
focus: true
|
focus: true
|
||||||
|
enabled: root.shouldBeVisible
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
wifiPasswordInput = text
|
wifiPasswordInput = text
|
||||||
}
|
}
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
NetworkService.connectToWifiWithPassword(wifiPasswordSSID,
|
NetworkService.connectToWifiWithPassword(wifiPasswordSSID,
|
||||||
passwordInput.text)
|
passwordInput.text)
|
||||||
wifiPasswordModalVisible = false
|
close()
|
||||||
wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
passwordInput.text = ""
|
passwordInput.text = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Component.onCompleted: {
|
||||||
id: focusTimer
|
if (root.shouldBeVisible) {
|
||||||
interval: 50
|
focusDelayTimer.start()
|
||||||
onTriggered: passwordInput.forceActiveFocus()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Timer {
|
||||||
focusTimer.start()
|
id: focusDelayTimer
|
||||||
|
interval: 100
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
if (root.shouldBeVisible) {
|
||||||
|
passwordInput.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onOpened() {
|
target: root
|
||||||
focusTimer.start()
|
function onShouldBeVisibleChanged() {
|
||||||
}
|
if (root.shouldBeVisible) {
|
||||||
|
focusDelayTimer.start()
|
||||||
function onVisibleChanged() {
|
|
||||||
if (root.visible) {
|
|
||||||
focusTimer.start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
target: root
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,7 +248,7 @@ DankModal {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
wifiPasswordModalVisible = false
|
close()
|
||||||
wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +283,7 @@ DankModal {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
NetworkService.connectToWifiWithPassword(wifiPasswordSSID,
|
NetworkService.connectToWifiWithPassword(wifiPasswordSSID,
|
||||||
passwordInput.text)
|
passwordInput.text)
|
||||||
wifiPasswordModalVisible = false
|
close()
|
||||||
wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
passwordInput.text = ""
|
passwordInput.text = ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,18 +10,14 @@ import qs.Modules.AppDrawer
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
PanelWindow {
|
DankPopout {
|
||||||
id: appDrawerPopout
|
id: appDrawerPopout
|
||||||
|
|
||||||
property bool isVisible: false
|
|
||||||
property real triggerX: Theme.spacingL
|
|
||||||
property real triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
|
||||||
property real triggerWidth: 40
|
|
||||||
property string triggerSection: "left"
|
property string triggerSection: "left"
|
||||||
property var triggerScreen: null
|
property var triggerScreen: null
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
appDrawerPopout.isVisible = true
|
open()
|
||||||
appLauncher.searchQuery = ""
|
appLauncher.searchQuery = ""
|
||||||
appLauncher.selectedIndex = 0
|
appLauncher.selectedIndex = 0
|
||||||
appLauncher.setCategory("All")
|
appLauncher.setCategory("All")
|
||||||
@@ -29,14 +25,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
appDrawerPopout.isVisible = false
|
close()
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
if (appDrawerPopout.isVisible)
|
|
||||||
hide()
|
|
||||||
else
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTriggerPosition(x, y, width, section, screen) {
|
function setTriggerPosition(x, y, width, section, screen) {
|
||||||
@@ -47,21 +36,15 @@ PanelWindow {
|
|||||||
triggerScreen = screen
|
triggerScreen = screen
|
||||||
}
|
}
|
||||||
|
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
popupWidth: 520
|
||||||
WlrLayershell.exclusiveZone: -1
|
popupHeight: 600
|
||||||
WlrLayershell.keyboardFocus: isVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
triggerX: Theme.spacingL
|
||||||
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
||||||
|
triggerWidth: 40
|
||||||
|
positioning: "center"
|
||||||
WlrLayershell.namespace: "quickshell-launcher"
|
WlrLayershell.namespace: "quickshell-launcher"
|
||||||
visible: isVisible
|
|
||||||
color: "transparent"
|
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
left: true
|
|
||||||
right: true
|
|
||||||
bottom: true
|
|
||||||
}
|
|
||||||
|
|
||||||
AppLauncher {
|
AppLauncher {
|
||||||
id: appLauncher
|
id: appLauncher
|
||||||
|
|
||||||
@@ -73,67 +56,8 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
content: Component {
|
||||||
anchors.fill: parent
|
Rectangle {
|
||||||
enabled: appDrawerPopout.isVisible
|
|
||||||
onClicked: function (mouse) {
|
|
||||||
var localPos = mapToItem(launcherLoader, mouse.x, mouse.y)
|
|
||||||
if (localPos.x < 0 || localPos.x > launcherLoader.width || localPos.y < 0
|
|
||||||
|| localPos.y > launcherLoader.height)
|
|
||||||
appDrawerPopout.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: launcherLoader
|
|
||||||
|
|
||||||
readonly property real popupWidth: 520
|
|
||||||
readonly property real popupHeight: 600
|
|
||||||
readonly property real screenWidth: appDrawerPopout.screen ? appDrawerPopout.screen.width : Screen.width
|
|
||||||
readonly property real screenHeight: appDrawerPopout.screen ? appDrawerPopout.screen.height : Screen.height
|
|
||||||
readonly property real calculatedX: {
|
|
||||||
var centerX = appDrawerPopout.triggerX + (appDrawerPopout.triggerWidth / 2) - (popupWidth / 2)
|
|
||||||
|
|
||||||
if (centerX >= Theme.spacingM
|
|
||||||
&& centerX + popupWidth <= screenWidth - Theme.spacingM)
|
|
||||||
return centerX
|
|
||||||
|
|
||||||
if (centerX < Theme.spacingM)
|
|
||||||
return Theme.spacingM
|
|
||||||
|
|
||||||
if (centerX + popupWidth > screenWidth - Theme.spacingM)
|
|
||||||
return screenWidth - popupWidth - Theme.spacingM
|
|
||||||
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
readonly property real calculatedY: appDrawerPopout.triggerY
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
active: appDrawerPopout.isVisible
|
|
||||||
width: popupWidth
|
|
||||||
height: popupHeight
|
|
||||||
x: calculatedX
|
|
||||||
y: calculatedY
|
|
||||||
opacity: appDrawerPopout.isVisible ? 1 : 0
|
|
||||||
scale: appDrawerPopout.isVisible ? 1 : 0.9
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: Rectangle {
|
|
||||||
id: launcherPanel
|
id: launcherPanel
|
||||||
|
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
@@ -177,12 +101,12 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (appDrawerPopout.isVisible)
|
if (appDrawerPopout.shouldBeVisible)
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
}
|
}
|
||||||
Keys.onPressed: function (event) {
|
Keys.onPressed: function (event) {
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
appDrawerPopout.hide()
|
appDrawerPopout.close()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key === Qt.Key_Down) {
|
} else if (event.key === Qt.Key_Down) {
|
||||||
appLauncher.selectNext()
|
appLauncher.selectNext()
|
||||||
@@ -262,15 +186,17 @@ PanelWindow {
|
|||||||
leftIconFocusedColor: Theme.primary
|
leftIconFocusedColor: Theme.primary
|
||||||
showClearButton: true
|
showClearButton: true
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
enabled: appDrawerPopout.isVisible
|
enabled: appDrawerPopout.shouldBeVisible
|
||||||
placeholderText: "Search applications..."
|
|
||||||
ignoreLeftRightKeys: true
|
ignoreLeftRightKeys: true
|
||||||
keyForwardTargets: [keyHandler]
|
keyForwardTargets: [keyHandler]
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
appLauncher.searchQuery = text
|
appLauncher.searchQuery = text
|
||||||
}
|
}
|
||||||
Keys.onPressed: function (event) {
|
Keys.onPressed: function (event) {
|
||||||
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
|
if (event.key === Qt.Key_Escape) {
|
||||||
|
appDrawerPopout.close()
|
||||||
|
event.accepted = true
|
||||||
|
} else if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
|
||||||
&& text.length > 0) {
|
&& text.length > 0) {
|
||||||
if (appLauncher.keyboardNavigationActive
|
if (appLauncher.keyboardNavigationActive
|
||||||
&& appLauncher.model.count > 0) {
|
&& appLauncher.model.count > 0) {
|
||||||
@@ -288,13 +214,13 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (appDrawerPopout.isVisible)
|
if (appDrawerPopout.shouldBeVisible)
|
||||||
searchField.forceActiveFocus()
|
searchField.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onIsVisibleChanged() {
|
function onShouldBeVisibleChanged() {
|
||||||
if (appDrawerPopout.isVisible)
|
if (appDrawerPopout.shouldBeVisible)
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
searchField.forceActiveFocus()
|
searchField.forceActiveFocus()
|
||||||
})
|
})
|
||||||
@@ -560,10 +486,10 @@ PanelWindow {
|
|||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
appList.itemClicked(index, model)
|
appList.itemClicked(index, model)
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
var globalPos = mapToGlobal(mouse.x, mouse.y)
|
var panelPos = mapToItem(contextMenu.parent, mouse.x, mouse.y)
|
||||||
appList.itemRightClicked(index, model,
|
appList.itemRightClicked(index, model,
|
||||||
globalPos.x,
|
panelPos.x,
|
||||||
globalPos.y)
|
panelPos.y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -737,10 +663,10 @@ PanelWindow {
|
|||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
appGrid.itemClicked(index, model)
|
appGrid.itemClicked(index, model)
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
var globalPos = mapToGlobal(mouse.x, mouse.y)
|
var panelPos = mapToItem(contextMenu.parent, mouse.x, mouse.y)
|
||||||
appGrid.itemRightClicked(index, model,
|
appGrid.itemRightClicked(index, model,
|
||||||
globalPos.x,
|
panelPos.x,
|
||||||
globalPos.y)
|
panelPos.y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -752,205 +678,237 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Popup {
|
Rectangle {
|
||||||
id: contextMenu
|
id: contextMenu
|
||||||
|
|
||||||
property var currentApp: null
|
property var currentApp: null
|
||||||
|
property bool menuVisible: false
|
||||||
|
|
||||||
function show(x, y, app) {
|
function show(x, y, app) {
|
||||||
currentApp = app
|
currentApp = app
|
||||||
if (!contextMenu.parent && typeof Overlay !== "undefined"
|
|
||||||
&& Overlay.overlay)
|
|
||||||
contextMenu.parent = Overlay.overlay
|
|
||||||
|
|
||||||
const menuWidth = 180
|
const menuWidth = 180
|
||||||
const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2
|
const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2
|
||||||
const screenWidth = Screen.width
|
|
||||||
const screenHeight = Screen.height
|
let finalX = x + 8
|
||||||
let finalX = x
|
let finalY = y + 8
|
||||||
let finalY = y
|
|
||||||
if (x + menuWidth > screenWidth - 20)
|
if (finalX + menuWidth > appDrawerPopout.popupWidth) {
|
||||||
finalX = x - menuWidth
|
finalX = x - menuWidth - 8
|
||||||
|
}
|
||||||
if (y + menuHeight > screenHeight - 20)
|
|
||||||
finalY = y - menuHeight
|
if (finalY + menuHeight > appDrawerPopout.popupHeight) {
|
||||||
|
finalY = y - menuHeight - 8
|
||||||
contextMenu.x = Math.max(20, finalX)
|
}
|
||||||
contextMenu.y = Math.max(20, finalY)
|
|
||||||
open()
|
finalX = Math.max(8, Math.min(finalX, appDrawerPopout.popupWidth - menuWidth - 8))
|
||||||
|
finalY = Math.max(8, Math.min(finalY, appDrawerPopout.popupHeight - menuHeight - 8))
|
||||||
|
|
||||||
|
contextMenu.x = finalX
|
||||||
|
contextMenu.y = finalY
|
||||||
|
contextMenu.visible = true
|
||||||
|
contextMenu.menuVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
contextMenu.menuVisible = false
|
||||||
|
Qt.callLater(() => {
|
||||||
|
contextMenu.visible = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: false
|
||||||
width: 180
|
width: 180
|
||||||
height: menuColumn.implicitHeight + Theme.spacingS * 2
|
height: menuColumn.implicitHeight + Theme.spacingS * 2
|
||||||
padding: 0
|
radius: Theme.cornerRadius
|
||||||
modal: false
|
color: Theme.popupBackground()
|
||||||
closePolicy: Popup.CloseOnEscape
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
onClosed: {
|
border.width: 1
|
||||||
closePolicy = Popup.CloseOnEscape
|
z: 1000
|
||||||
}
|
opacity: menuVisible ? 1 : 0
|
||||||
onOpened: {
|
scale: menuVisible ? 1 : 0.85
|
||||||
outsideClickTimer.start()
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: 4
|
||||||
|
anchors.leftMargin: 2
|
||||||
|
anchors.rightMargin: -2
|
||||||
|
anchors.bottomMargin: -4
|
||||||
|
radius: parent.radius
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.15)
|
||||||
|
z: parent.z - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Column {
|
||||||
id: outsideClickTimer
|
id: menuColumn
|
||||||
|
|
||||||
interval: 100
|
anchors.fill: parent
|
||||||
onTriggered: {
|
anchors.margins: Theme.spacingS
|
||||||
contextMenu.closePolicy = Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
spacing: 1
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
Rectangle {
|
||||||
color: "transparent"
|
width: parent.width
|
||||||
}
|
height: 32
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: pinMouseArea.containsMouse ? Qt.rgba(Theme.primary.r,
|
||||||
|
Theme.primary.g,
|
||||||
|
Theme.primary.b,
|
||||||
|
0.12) : "transparent"
|
||||||
|
|
||||||
contentItem: Rectangle {
|
Row {
|
||||||
color: Theme.popupBackground()
|
anchors.left: parent.left
|
||||||
radius: Theme.cornerRadius
|
anchors.leftMargin: Theme.spacingS
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
Theme.outline.b, 0.08)
|
spacing: Theme.spacingS
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Column {
|
DankIcon {
|
||||||
id: menuColumn
|
name: {
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingS
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: 32
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: pinMouseArea.containsMouse ? Qt.rgba(Theme.primary.r,
|
|
||||||
Theme.primary.g,
|
|
||||||
Theme.primary.b,
|
|
||||||
0.12) : "transparent"
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: {
|
|
||||||
if (!contextMenu.currentApp
|
|
||||||
|| !contextMenu.currentApp.desktopEntry)
|
|
||||||
return "push_pin"
|
|
||||||
|
|
||||||
var appId = contextMenu.currentApp.desktopEntry.id
|
|
||||||
|| contextMenu.currentApp.desktopEntry.execString || ""
|
|
||||||
return SessionData.isPinnedApp(appId) ? "keep_off" : "push_pin"
|
|
||||||
}
|
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: Theme.surfaceText
|
|
||||||
opacity: 0.7
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (!contextMenu.currentApp
|
|
||||||
|| !contextMenu.currentApp.desktopEntry)
|
|
||||||
return "Pin to Dock"
|
|
||||||
|
|
||||||
var appId = contextMenu.currentApp.desktopEntry.id
|
|
||||||
|| contextMenu.currentApp.desktopEntry.execString || ""
|
|
||||||
return SessionData.isPinnedApp(
|
|
||||||
appId) ? "Unpin from Dock" : "Pin to Dock"
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: pinMouseArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
if (!contextMenu.currentApp
|
if (!contextMenu.currentApp
|
||||||
|| !contextMenu.currentApp.desktopEntry)
|
|| !contextMenu.currentApp.desktopEntry)
|
||||||
return
|
return "push_pin"
|
||||||
|
|
||||||
var appId = contextMenu.currentApp.desktopEntry.id
|
var appId = contextMenu.currentApp.desktopEntry.id
|
||||||
|| contextMenu.currentApp.desktopEntry.execString || ""
|
|| contextMenu.currentApp.desktopEntry.execString || ""
|
||||||
if (SessionData.isPinnedApp(appId))
|
return SessionData.isPinnedApp(appId) ? "keep_off" : "push_pin"
|
||||||
SessionData.removePinnedApp(appId)
|
|
||||||
else
|
|
||||||
SessionData.addPinnedApp(appId)
|
|
||||||
contextMenu.close()
|
|
||||||
}
|
}
|
||||||
}
|
size: Theme.iconSize - 2
|
||||||
}
|
color: Theme.surfaceText
|
||||||
|
opacity: 0.7
|
||||||
Rectangle {
|
|
||||||
width: parent.width - Theme.spacingS * 2
|
|
||||||
height: 5
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.width
|
|
||||||
height: 1
|
|
||||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
|
||||||
Theme.outline.b, 0.2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: 32
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: launchMouseArea.containsMouse ? Qt.rgba(Theme.primary.r,
|
|
||||||
Theme.primary.g,
|
|
||||||
Theme.primary.b,
|
|
||||||
0.12) : "transparent"
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "launch"
|
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: Theme.surfaceText
|
|
||||||
opacity: 0.7
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Launch"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
StyledText {
|
||||||
id: launchMouseArea
|
text: {
|
||||||
|
if (!contextMenu.currentApp
|
||||||
|
|| !contextMenu.currentApp.desktopEntry)
|
||||||
|
return "Pin to Dock"
|
||||||
|
|
||||||
anchors.fill: parent
|
var appId = contextMenu.currentApp.desktopEntry.id
|
||||||
hoverEnabled: true
|
|| contextMenu.currentApp.desktopEntry.execString || ""
|
||||||
cursorShape: Qt.PointingHandCursor
|
return SessionData.isPinnedApp(
|
||||||
onClicked: {
|
appId) ? "Unpin from Dock" : "Pin to Dock"
|
||||||
if (contextMenu.currentApp)
|
|
||||||
appLauncher.launchApp(contextMenu.currentApp)
|
|
||||||
|
|
||||||
contextMenu.close()
|
|
||||||
}
|
}
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: pinMouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (!contextMenu.currentApp
|
||||||
|
|| !contextMenu.currentApp.desktopEntry)
|
||||||
|
return
|
||||||
|
|
||||||
|
var appId = contextMenu.currentApp.desktopEntry.id
|
||||||
|
|| contextMenu.currentApp.desktopEntry.execString || ""
|
||||||
|
if (SessionData.isPinnedApp(appId))
|
||||||
|
SessionData.removePinnedApp(appId)
|
||||||
|
else
|
||||||
|
SessionData.addPinnedApp(appId)
|
||||||
|
contextMenu.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width - Theme.spacingS * 2
|
||||||
|
height: 5
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 32
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: launchMouseArea.containsMouse ? Qt.rgba(Theme.primary.r,
|
||||||
|
Theme.primary.g,
|
||||||
|
Theme.primary.b,
|
||||||
|
0.12) : "transparent"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "launch"
|
||||||
|
size: Theme.iconSize - 2
|
||||||
|
color: Theme.surfaceText
|
||||||
|
opacity: 0.7
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Launch"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: launchMouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (contextMenu.currentApp)
|
||||||
|
appLauncher.launchApp(contextMenu.currentApp)
|
||||||
|
|
||||||
|
contextMenu.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: contextMenu.visible
|
||||||
|
z: 999
|
||||||
|
onClicked: {
|
||||||
|
contextMenu.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
x: contextMenu.x
|
||||||
|
y: contextMenu.y
|
||||||
|
width: contextMenu.width
|
||||||
|
height: contextMenu.height
|
||||||
|
onClicked: {
|
||||||
|
// Prevent closing when clicking on the menu itself
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ PanelWindow {
|
|||||||
|
|
||||||
readonly property bool hasActiveMedia: MprisController.activePlayer !== null
|
readonly property bool hasActiveMedia: MprisController.activePlayer !== null
|
||||||
property bool calendarVisible: false
|
property bool calendarVisible: false
|
||||||
|
property bool shouldBeVisible: false
|
||||||
property real triggerX: (Screen.width - 480) / 2
|
property real triggerX: (Screen.width - 480) / 2
|
||||||
property real triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + 4
|
property real triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + 4
|
||||||
property real triggerWidth: 80
|
property real triggerWidth: 80
|
||||||
@@ -28,13 +29,29 @@ PanelWindow {
|
|||||||
triggerScreen = screen
|
triggerScreen = screen
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: calendarVisible
|
visible: calendarVisible || closeTimer.running
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
onCalendarVisibleChanged: {
|
onCalendarVisibleChanged: {
|
||||||
if (calendarVisible) {
|
if (calendarVisible) {
|
||||||
|
closeTimer.stop()
|
||||||
|
shouldBeVisible = true
|
||||||
|
visible = true
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
calendarGrid.loadEventsForMonth()
|
calendarGrid.loadEventsForMonth()
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
shouldBeVisible = false
|
||||||
|
closeTimer.restart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: closeTimer
|
||||||
|
interval: Theme.mediumDuration + 50
|
||||||
|
onTriggered: {
|
||||||
|
if (!shouldBeVisible) {
|
||||||
|
visible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
@@ -45,7 +62,7 @@ PanelWindow {
|
|||||||
implicitHeight: 600
|
implicitHeight: 600
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
WlrLayershell.keyboardFocus: calendarVisible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: shouldBeVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
@@ -123,8 +140,8 @@ PanelWindow {
|
|||||||
Theme.outline.b, 0.08)
|
Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
opacity: calendarVisible ? 1 : 0
|
opacity: shouldBeVisible ? 1 : 0
|
||||||
scale: calendarVisible ? 1 : 0.9
|
scale: shouldBeVisible ? 1 : 0.9
|
||||||
x: calculatedX
|
x: calculatedX
|
||||||
y: root.triggerY
|
y: root.triggerY
|
||||||
onOpacityChanged: {
|
onOpacityChanged: {
|
||||||
@@ -166,7 +183,7 @@ PanelWindow {
|
|||||||
radius: parent.radius
|
radius: parent.radius
|
||||||
|
|
||||||
SequentialAnimation on opacity {
|
SequentialAnimation on opacity {
|
||||||
running: calendarVisible
|
running: shouldBeVisible
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
|
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -296,7 +313,7 @@ PanelWindow {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: -1
|
z: -1
|
||||||
enabled: calendarVisible
|
enabled: shouldBeVisible
|
||||||
onClicked: function (mouse) {
|
onClicked: function (mouse) {
|
||||||
var localPos = mapToItem(mainContainer, mouse.x, mouse.y)
|
var localPos = mapToItem(mainContainer, mouse.x, mouse.y)
|
||||||
if (localPos.x < 0 || localPos.x > mainContainer.width || localPos.y < 0
|
if (localPos.x < 0 || localPos.x > mainContainer.width || localPos.y < 0
|
||||||
|
|||||||
@@ -11,17 +11,13 @@ import qs.Modules.ControlCenter
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
PanelWindow {
|
DankPopout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool controlCenterVisible: false
|
|
||||||
property string currentTab: "network"
|
property string currentTab: "network"
|
||||||
property bool powerOptionsExpanded: false
|
property bool powerOptionsExpanded: false
|
||||||
property var triggerScreen: null
|
|
||||||
property real triggerX: Screen.width - 600 - Theme.spacingL
|
|
||||||
property real triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
|
||||||
property real triggerWidth: 80
|
|
||||||
property string triggerSection: "right"
|
property string triggerSection: "right"
|
||||||
|
property var triggerScreen: null
|
||||||
|
|
||||||
function setTriggerPosition(x, y, width, section, screen) {
|
function setTriggerPosition(x, y, width, section, screen) {
|
||||||
triggerX = x
|
triggerX = x
|
||||||
@@ -34,82 +30,42 @@ PanelWindow {
|
|||||||
signal powerActionRequested(string action, string title, string message)
|
signal powerActionRequested(string action, string title, string message)
|
||||||
signal lockRequested
|
signal lockRequested
|
||||||
|
|
||||||
visible: controlCenterVisible
|
popupWidth: 600
|
||||||
|
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : (powerOptionsExpanded ? 570 : 500)
|
||||||
|
triggerX: Screen.width - 600 - Theme.spacingL
|
||||||
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
||||||
|
triggerWidth: 80
|
||||||
|
positioning: "center"
|
||||||
|
WlrLayershell.namespace: "quickshell-controlcenter"
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
onVisibleChanged: {
|
shouldBeVisible: false
|
||||||
NetworkService.autoRefreshEnabled = visible && NetworkService.wifiEnabled
|
visible: shouldBeVisible
|
||||||
if (!visible && BluetoothService.adapter
|
|
||||||
&& BluetoothService.adapter.discovering)
|
|
||||||
BluetoothService.adapter.discovering = false
|
|
||||||
|
|
||||||
if (visible && UserInfoService)
|
onShouldBeVisibleChanged: {
|
||||||
UserInfoService.getUptime()
|
if (shouldBeVisible) {
|
||||||
}
|
NetworkService.autoRefreshEnabled = NetworkService.wifiEnabled
|
||||||
implicitWidth: 600
|
if (UserInfoService)
|
||||||
implicitHeight: 500
|
UserInfoService.getUptime()
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
} else {
|
||||||
WlrLayershell.exclusiveZone: -1
|
NetworkService.autoRefreshEnabled = false
|
||||||
WlrLayershell.keyboardFocus: controlCenterVisible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
if (BluetoothService.adapter && BluetoothService.adapter.discovering)
|
||||||
color: "transparent"
|
BluetoothService.adapter.discovering = false
|
||||||
|
}
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
left: true
|
|
||||||
right: true
|
|
||||||
bottom: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
content: Component {
|
||||||
id: contentLoader
|
Rectangle {
|
||||||
|
id: controlContent
|
||||||
readonly property real screenWidth: root.screen ? root.screen.width : Screen.width
|
|
||||||
readonly property real screenHeight: root.screen ? root.screen.height : Screen.height
|
implicitHeight: {
|
||||||
readonly property real targetWidth: Math.min(
|
let baseHeight = Theme.spacingL * 2
|
||||||
600, screenWidth - Theme.spacingL * 2)
|
baseHeight += 90 // user header
|
||||||
|
baseHeight += (powerOptionsExpanded ? 60 : 0) + Theme.spacingL // power options
|
||||||
asynchronous: true
|
baseHeight += 52 + Theme.spacingL // tab bar
|
||||||
active: controlCenterVisible
|
baseHeight += 280 // tab content area
|
||||||
width: targetWidth
|
return baseHeight
|
||||||
height: root.powerOptionsExpanded ? 570 : 500
|
|
||||||
y: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
|
||||||
x: {
|
|
||||||
var centerX = root.triggerX + (root.triggerWidth / 2) - (targetWidth / 2)
|
|
||||||
|
|
||||||
if (centerX >= Theme.spacingM
|
|
||||||
&& centerX + targetWidth <= screenWidth - Theme.spacingM) {
|
|
||||||
return centerX
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (centerX < Theme.spacingM) {
|
|
||||||
return Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerX + targetWidth > screenWidth - Theme.spacingM) {
|
|
||||||
return screenWidth - targetWidth - Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
opacity: controlCenterVisible ? 1 : 0
|
|
||||||
scale: controlCenterVisible ? 1 : 0.9
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: Rectangle {
|
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
@@ -118,13 +74,15 @@ PanelWindow {
|
|||||||
antialiasing: true
|
antialiasing: true
|
||||||
smooth: true
|
smooth: true
|
||||||
focus: true
|
focus: true
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (controlCenterVisible)
|
if (root.shouldBeVisible)
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onPressed: function (event) {
|
Keys.onPressed: function (event) {
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
controlCenterVisible = false
|
root.close()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else {
|
} else {
|
||||||
event.accepted = false
|
event.accepted = false
|
||||||
@@ -132,10 +90,10 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onControlCenterVisibleChanged() {
|
function onShouldBeVisibleChanged() {
|
||||||
if (controlCenterVisible)
|
if (root.shouldBeVisible)
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
parent.forceActiveFocus()
|
controlContent.forceActiveFocus()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
target: root
|
target: root
|
||||||
@@ -294,7 +252,7 @@ PanelWindow {
|
|||||||
hoverColor: Qt.rgba(Theme.primary.r, Theme.primary.g,
|
hoverColor: Qt.rgba(Theme.primary.r, Theme.primary.g,
|
||||||
Theme.primary.b, 0.12)
|
Theme.primary.b, 0.12)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterVisible = false
|
root.close()
|
||||||
root.lockRequested()
|
root.lockRequested()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,7 +321,7 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
root.powerOptionsExpanded = !root.powerOptionsExpanded
|
root.powerOptionsExpanded = !root.powerOptionsExpanded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,7 +345,7 @@ PanelWindow {
|
|||||||
hoverColor: Qt.rgba(Theme.primary.r, Theme.primary.g,
|
hoverColor: Qt.rgba(Theme.primary.r, Theme.primary.g,
|
||||||
Theme.primary.b, 0.12)
|
Theme.primary.b, 0.12)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterVisible = false
|
root.close()
|
||||||
settingsModal.show()
|
settingsModal.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -451,8 +409,9 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
root.powerOptionsExpanded = false
|
root.powerOptionsExpanded = false
|
||||||
|
root.close()
|
||||||
root.powerActionRequested(
|
root.powerActionRequested(
|
||||||
"logout", "Logout",
|
"logout", "Logout",
|
||||||
"Are you sure you want to logout?")
|
"Are you sure you want to logout?")
|
||||||
@@ -506,8 +465,9 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
root.powerOptionsExpanded = false
|
root.powerOptionsExpanded = false
|
||||||
|
root.close()
|
||||||
root.powerActionRequested(
|
root.powerActionRequested(
|
||||||
"reboot", "Restart",
|
"reboot", "Restart",
|
||||||
"Are you sure you want to restart?")
|
"Are you sure you want to restart?")
|
||||||
@@ -561,8 +521,9 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
root.powerOptionsExpanded = false
|
root.powerOptionsExpanded = false
|
||||||
|
root.close()
|
||||||
root.powerActionRequested(
|
root.powerActionRequested(
|
||||||
"suspend", "Suspend",
|
"suspend", "Suspend",
|
||||||
"Are you sure you want to suspend?")
|
"Are you sure you want to suspend?")
|
||||||
@@ -616,8 +577,9 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
root.powerOptionsExpanded = false
|
root.powerOptionsExpanded = false
|
||||||
|
root.close()
|
||||||
root.powerActionRequested(
|
root.powerActionRequested(
|
||||||
"poweroff", "Shutdown",
|
"poweroff", "Shutdown",
|
||||||
"Are you sure you want to shutdown?")
|
"Are you sure you want to shutdown?")
|
||||||
@@ -768,23 +730,12 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on height {
|
Behavior on implicitHeight {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration // Faster for height changes
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
z: -1
|
|
||||||
onClicked: function (mouse) {
|
|
||||||
var localPos = mapToItem(contentLoader, mouse.x, mouse.y)
|
|
||||||
if (localPos.x < 0 || localPos.x > contentLoader.width || localPos.y < 0
|
|
||||||
|| localPos.y > contentLoader.height)
|
|
||||||
controlCenterVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -131,9 +131,7 @@ Rectangle {
|
|||||||
wifiContextMenuWindow.networkData.ssid)
|
wifiContextMenuWindow.networkData.ssid)
|
||||||
} else if (wifiContextMenuWindow.networkData.secured) {
|
} else if (wifiContextMenuWindow.networkData.secured) {
|
||||||
if (wifiPasswordModalRef) {
|
if (wifiPasswordModalRef) {
|
||||||
wifiPasswordModalRef.wifiPasswordSSID = wifiContextMenuWindow.networkData.ssid
|
wifiPasswordModalRef.show(wifiContextMenuWindow.networkData.ssid)
|
||||||
wifiPasswordModalRef.wifiPasswordInput = ""
|
|
||||||
wifiPasswordModalRef.wifiPasswordModalVisible = true
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NetworkService.connectToWifi(
|
NetworkService.connectToWifi(
|
||||||
|
|||||||
@@ -303,9 +303,7 @@ Column {
|
|||||||
NetworkService.connectToWifi(modelData.ssid)
|
NetworkService.connectToWifi(modelData.ssid)
|
||||||
} else if (modelData.secured) {
|
} else if (modelData.secured) {
|
||||||
if (wifiPasswordModalRef) {
|
if (wifiPasswordModalRef) {
|
||||||
wifiPasswordModalRef.wifiPasswordSSID = modelData.ssid
|
wifiPasswordModalRef.show(modelData.ssid)
|
||||||
wifiPasswordModalRef.wifiPasswordInput = ""
|
|
||||||
wifiPasswordModalRef.wifiPasswordModalVisible = true
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NetworkService.connectToWifi(modelData.ssid)
|
NetworkService.connectToWifi(modelData.ssid)
|
||||||
|
|||||||
@@ -11,10 +11,7 @@ PanelWindow {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool powerMenuVisible: false
|
property bool powerMenuVisible: false
|
||||||
property bool powerConfirmVisible: false
|
signal powerActionRequested(string action, string title, string message)
|
||||||
property string powerConfirmAction: ""
|
|
||||||
property string powerConfirmTitle: ""
|
|
||||||
property string powerConfirmMessage: ""
|
|
||||||
|
|
||||||
visible: powerMenuVisible
|
visible: powerMenuVisible
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
@@ -137,10 +134,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "logout"
|
root.powerActionRequested("logout", "Log Out", "Are you sure you want to log out?")
|
||||||
root.powerConfirmTitle = "Log Out"
|
|
||||||
root.powerConfirmMessage = "Are you sure you want to log out?"
|
|
||||||
root.powerConfirmVisible = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,10 +181,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "suspend"
|
root.powerActionRequested("suspend", "Suspend", "Are you sure you want to suspend the system?")
|
||||||
root.powerConfirmTitle = "Suspend"
|
|
||||||
root.powerConfirmMessage = "Are you sure you want to suspend the system?"
|
|
||||||
root.powerConfirmVisible = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,10 +228,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "reboot"
|
root.powerActionRequested("reboot", "Reboot", "Are you sure you want to reboot the system?")
|
||||||
root.powerConfirmTitle = "Reboot"
|
|
||||||
root.powerConfirmMessage = "Are you sure you want to reboot the system?"
|
|
||||||
root.powerConfirmVisible = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,10 +275,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "poweroff"
|
root.powerActionRequested("poweroff", "Power Off", "Are you sure you want to power off the system?")
|
||||||
root.powerConfirmTitle = "Power Off"
|
|
||||||
root.powerConfirmMessage = "Are you sure you want to power off the system?"
|
|
||||||
root.powerConfirmVisible = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,8 +187,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: root.appData && root.appData.windows
|
visible: !!(root.appData && root.appData.windows && root.appData.windows.count > 0)
|
||||||
&& root.appData.windows.count > 0
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 1
|
||||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
@@ -236,16 +235,14 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: root.appData && root.appData.windows
|
visible: !!(root.appData && root.appData.windows && root.appData.windows.count > 1)
|
||||||
&& root.appData.windows.count > 1
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 1
|
||||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: root.appData && root.appData.windows
|
visible: !!(root.appData && root.appData.windows && root.appData.windows.count > 1)
|
||||||
&& root.appData.windows.count > 1
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 28
|
height: 28
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|||||||
@@ -9,14 +9,12 @@ import qs.Services
|
|||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
import qs.Modules.Notifications.Center
|
import qs.Modules.Notifications.Center
|
||||||
|
|
||||||
PanelWindow {
|
DankPopout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool notificationHistoryVisible: false
|
property bool notificationHistoryVisible: false
|
||||||
property real triggerX: Screen.width - 400 - Theme.spacingL
|
|
||||||
property real triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
|
||||||
property real triggerWidth: 40
|
|
||||||
property string triggerSection: "right"
|
property string triggerSection: "right"
|
||||||
|
property var triggerScreen: null
|
||||||
|
|
||||||
NotificationKeyboardController {
|
NotificationKeyboardController {
|
||||||
id: keyboardController
|
id: keyboardController
|
||||||
@@ -25,185 +23,143 @@ PanelWindow {
|
|||||||
onClose: function() { notificationHistoryVisible = false }
|
onClose: function() { notificationHistoryVisible = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationKeyboardHints {
|
|
||||||
id: keyboardHints
|
|
||||||
anchors.bottom: mainRect.bottom
|
|
||||||
anchors.left: mainRect.left
|
|
||||||
anchors.right: mainRect.right
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
showHints: keyboardController.showKeyboardHints
|
|
||||||
z: 200
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTriggerPosition(x, y, width, section) {
|
function setTriggerPosition(x, y, width, section, screen) {
|
||||||
triggerX = x
|
triggerX = x
|
||||||
triggerY = y
|
triggerY = y
|
||||||
triggerWidth = width
|
triggerWidth = width
|
||||||
triggerSection = section
|
triggerSection = section
|
||||||
|
triggerScreen = screen
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: notificationHistoryVisible
|
popupWidth: 400
|
||||||
|
popupHeight: {
|
||||||
|
let baseHeight = Theme.spacingL * 2
|
||||||
|
baseHeight += 40 // notificationHeader height estimate
|
||||||
|
baseHeight += 0 // notificationSettings when collapsed
|
||||||
|
baseHeight += Theme.spacingM * 2
|
||||||
|
let listHeight = 200 // default list height
|
||||||
|
baseHeight += Math.min(listHeight, 600)
|
||||||
|
return Math.max(300, Math.min(baseHeight, Screen.height * 0.8))
|
||||||
|
}
|
||||||
|
triggerX: Screen.width - 400 - Theme.spacingL
|
||||||
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
||||||
|
triggerWidth: 40
|
||||||
|
positioning: "center"
|
||||||
|
WlrLayershell.namespace: "quickshell-notifications"
|
||||||
|
screen: triggerScreen
|
||||||
|
shouldBeVisible: notificationHistoryVisible
|
||||||
|
visible: shouldBeVisible
|
||||||
|
|
||||||
onNotificationHistoryVisibleChanged: {
|
onNotificationHistoryVisibleChanged: {
|
||||||
NotificationService.disablePopups(notificationHistoryVisible)
|
if (notificationHistoryVisible) {
|
||||||
}
|
open()
|
||||||
implicitWidth: 400
|
NotificationService.disablePopups(true)
|
||||||
implicitHeight: Math.min(Screen.height * 0.8, 400)
|
} else {
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
close()
|
||||||
WlrLayershell.exclusiveZone: -1
|
NotificationService.disablePopups(false)
|
||||||
WlrLayershell.keyboardFocus: notificationHistoryVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
left: true
|
|
||||||
right: true
|
|
||||||
bottom: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
notificationHistoryVisible = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
content: Component {
|
||||||
id: mainRect
|
Rectangle {
|
||||||
|
id: notificationContent
|
||||||
readonly property real popupWidth: 400
|
|
||||||
readonly property real calculatedX: {
|
|
||||||
var centerX = root.triggerX + (root.triggerWidth / 2) - (popupWidth / 2)
|
|
||||||
|
|
||||||
if (centerX >= Theme.spacingM
|
|
||||||
&& centerX + popupWidth <= Screen.width - Theme.spacingM) {
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerX < Theme.spacingM) {
|
|
||||||
return Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerX + popupWidth > Screen.width - Theme.spacingM) {
|
|
||||||
return Screen.width - popupWidth - Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
|
|
||||||
width: popupWidth
|
|
||||||
height: {
|
|
||||||
let baseHeight = Theme.spacingL * 2
|
|
||||||
baseHeight += notificationHeader.height
|
|
||||||
// Use the final content height when expanded, not the animating height
|
|
||||||
baseHeight += (notificationSettings.expanded ? notificationSettings.contentHeight : 0)
|
|
||||||
baseHeight += Theme.spacingM * 2
|
|
||||||
let listHeight = notificationList.listContentHeight
|
|
||||||
if (NotificationService.groupedNotifications.length === 0)
|
|
||||||
listHeight = 200
|
|
||||||
|
|
||||||
baseHeight += Math.min(listHeight, 600)
|
|
||||||
return Math.max(300, Math.min(baseHeight, Screen.height * 0.8))
|
|
||||||
}
|
|
||||||
x: calculatedX
|
|
||||||
y: root.triggerY
|
|
||||||
color: Theme.popupBackground()
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
|
||||||
Theme.outline.b, 0.08)
|
|
||||||
border.width: 1
|
|
||||||
opacity: notificationHistoryVisible ? 1 : 0
|
|
||||||
scale: notificationHistoryVisible ? 1 : 0.9
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FocusScope {
|
|
||||||
id: contentColumn
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
|
implicitHeight: {
|
||||||
|
let baseHeight = Theme.spacingL * 2
|
||||||
|
baseHeight += notificationHeader.height
|
||||||
|
baseHeight += (notificationSettings.expanded ? notificationSettings.contentHeight : 0)
|
||||||
|
baseHeight += Theme.spacingM * 2
|
||||||
|
let listHeight = notificationList.listContentHeight
|
||||||
|
if (NotificationService.groupedNotifications.length === 0)
|
||||||
|
listHeight = 200
|
||||||
|
baseHeight += Math.min(listHeight, 600)
|
||||||
|
return Math.max(300, Math.min(baseHeight, root.screen ? root.screen.height * 0.8 : Screen.height * 0.8))
|
||||||
|
}
|
||||||
|
|
||||||
|
color: Theme.popupBackground()
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
|
Theme.outline.b, 0.08)
|
||||||
|
border.width: 1
|
||||||
|
focus: true
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (notificationHistoryVisible)
|
if (root.shouldBeVisible)
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onPressed: function(event) {
|
Keys.onPressed: function(event) {
|
||||||
keyboardController.handleKey(event)
|
keyboardController.handleKey(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: contentColumnInner
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onNotificationHistoryVisibleChanged() {
|
function onShouldBeVisibleChanged() {
|
||||||
if (notificationHistoryVisible)
|
if (root.shouldBeVisible)
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
contentColumn.forceActiveFocus()
|
notificationContent.forceActiveFocus()
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
contentColumn.focus = false
|
notificationContent.focus = false
|
||||||
}
|
}
|
||||||
target: root
|
target: root
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationHeader {
|
FocusScope {
|
||||||
id: notificationHeader
|
id: contentColumn
|
||||||
keyboardController: keyboardController
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationSettings {
|
|
||||||
id: notificationSettings
|
|
||||||
expanded: notificationHeader.showSettings
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyboardNavigatedNotificationList {
|
anchors.fill: parent
|
||||||
id: notificationList
|
anchors.margins: Theme.spacingL
|
||||||
|
focus: true
|
||||||
width: parent.width
|
|
||||||
height: parent.height - notificationHeader.height - notificationSettings.height - contentColumnInner.spacing * 2
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Column {
|
||||||
if (keyboardController && notificationList) {
|
id: contentColumnInner
|
||||||
keyboardController.listView = notificationList
|
anchors.fill: parent
|
||||||
notificationList.keyboardController = keyboardController
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
NotificationHeader {
|
||||||
|
id: notificationHeader
|
||||||
|
keyboardController: keyboardController
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationSettings {
|
||||||
|
id: notificationSettings
|
||||||
|
expanded: notificationHeader.showSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardNavigatedNotificationList {
|
||||||
|
id: notificationList
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - notificationHeader.height - notificationSettings.height - contentColumnInner.spacing * 2
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (keyboardController && notificationList) {
|
||||||
|
keyboardController.listView = notificationList
|
||||||
|
notificationList.keyboardController = keyboardController
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotificationKeyboardHints {
|
||||||
|
id: keyboardHints
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
showHints: keyboardController.showKeyboardHints
|
||||||
|
z: 200
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
Behavior on height {
|
NumberAnimation {
|
||||||
NumberAnimation {
|
duration: Anims.durShort
|
||||||
duration: Anims.durShort
|
easing.type: Easing.BezierSpline
|
||||||
easing.type: Easing.BezierSpline
|
easing.bezierCurve: Anims.emphasized
|
||||||
easing.bezierCurve: Anims.emphasized
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,14 +11,10 @@ import qs.Modules.ProcessList
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
PanelWindow {
|
DankPopout {
|
||||||
id: processListPopout
|
id: processListPopout
|
||||||
|
|
||||||
property bool isVisible: false
|
|
||||||
property var parentWidget: null
|
property var parentWidget: null
|
||||||
property real triggerX: Screen.width - 600 - Theme.spacingL
|
|
||||||
property real triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
|
||||||
property real triggerWidth: 55
|
|
||||||
property string triggerSection: "right"
|
property string triggerSection: "right"
|
||||||
property var triggerScreen: null
|
property var triggerScreen: null
|
||||||
|
|
||||||
@@ -31,109 +27,33 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
isVisible = false
|
close()
|
||||||
if (processContextMenu.visible)
|
if (processContextMenu.visible)
|
||||||
processContextMenu.close()
|
processContextMenu.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
isVisible = true
|
open()
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
popupWidth: 600
|
||||||
if (isVisible)
|
popupHeight: 600
|
||||||
hide()
|
triggerX: Screen.width - 600 - Theme.spacingL
|
||||||
else
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
||||||
show()
|
triggerWidth: 55
|
||||||
}
|
positioning: "center"
|
||||||
|
WlrLayershell.namespace: "quickshell-processlist"
|
||||||
visible: isVisible
|
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
implicitWidth: 600
|
visible: shouldBeVisible
|
||||||
implicitHeight: 600
|
shouldBeVisible: false
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
|
||||||
WlrLayershell.exclusiveZone: -1
|
|
||||||
WlrLayershell.keyboardFocus: isVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Ref {
|
Ref {
|
||||||
service: DgopService
|
service: DgopService
|
||||||
}
|
}
|
||||||
|
|
||||||
anchors {
|
content: Component {
|
||||||
top: true
|
Rectangle {
|
||||||
left: true
|
id: processListContent
|
||||||
right: true
|
|
||||||
bottom: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: function (mouse) {
|
|
||||||
var localPos = mapToItem(contentLoader, mouse.x, mouse.y)
|
|
||||||
if (localPos.x < 0 || localPos.x > contentLoader.width || localPos.y < 0
|
|
||||||
|| localPos.y > contentLoader.height)
|
|
||||||
processListPopout.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: contentLoader
|
|
||||||
|
|
||||||
readonly property real screenWidth: processListPopout.screen ? processListPopout.screen.width : Screen.width
|
|
||||||
readonly property real screenHeight: processListPopout.screen ? processListPopout.screen.height : Screen.height
|
|
||||||
readonly property real targetWidth: Math.min(
|
|
||||||
600, screenWidth - Theme.spacingL * 2)
|
|
||||||
readonly property real targetHeight: Math.min(
|
|
||||||
600,
|
|
||||||
screenHeight - Theme.barHeight - Theme.spacingS * 2)
|
|
||||||
readonly property real calculatedX: {
|
|
||||||
var centerX = processListPopout.triggerX + (processListPopout.triggerWidth
|
|
||||||
/ 2) - (targetWidth / 2)
|
|
||||||
|
|
||||||
if (centerX >= Theme.spacingM
|
|
||||||
&& centerX + targetWidth <= screenWidth - Theme.spacingM) {
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerX < Theme.spacingM) {
|
|
||||||
return Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerX + targetWidth > screenWidth - Theme.spacingM) {
|
|
||||||
return screenWidth - targetWidth - Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
active: processListPopout.isVisible
|
|
||||||
width: targetWidth
|
|
||||||
height: targetHeight
|
|
||||||
y: processListPopout.triggerY
|
|
||||||
x: calculatedX
|
|
||||||
opacity: processListPopout.isVisible ? 1 : 0
|
|
||||||
scale: processListPopout.isVisible ? 1 : 0.9
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: Rectangle {
|
|
||||||
id: dropdownContent
|
|
||||||
|
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
@@ -144,22 +64,24 @@ PanelWindow {
|
|||||||
antialiasing: true
|
antialiasing: true
|
||||||
smooth: true
|
smooth: true
|
||||||
focus: true
|
focus: true
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (processListPopout.isVisible)
|
if (processListPopout.shouldBeVisible)
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onPressed: function (event) {
|
Keys.onPressed: function (event) {
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
processListPopout.hide()
|
processListPopout.close()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onIsVisibleChanged() {
|
function onShouldBeVisibleChanged() {
|
||||||
if (processListPopout.isVisible)
|
if (processListPopout.shouldBeVisible)
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
dropdownContent.forceActiveFocus()
|
processListContent.forceActiveFocus()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
target: processListPopout
|
target: processListPopout
|
||||||
@@ -211,4 +133,4 @@ PanelWindow {
|
|||||||
ProcessContextMenu {
|
ProcessContextMenu {
|
||||||
id: processContextMenu
|
id: processContextMenu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@ Item {
|
|||||||
|
|
||||||
property alias profileBrowser: profileBrowser
|
property alias profileBrowser: profileBrowser
|
||||||
property alias wallpaperBrowser: wallpaperBrowser
|
property alias wallpaperBrowser: wallpaperBrowser
|
||||||
|
property var parentModal: null
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
// Access WallpaperCyclingService to ensure it's initialized
|
// Access WallpaperCyclingService to ensure it's initialized
|
||||||
@@ -238,7 +239,11 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
profileBrowser.visible = true;
|
if (parentModal) {
|
||||||
|
parentModal.allowFocusOverride = true;
|
||||||
|
parentModal.shouldHaveFocus = false;
|
||||||
|
}
|
||||||
|
profileBrowser.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +442,11 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
wallpaperBrowser.visible = true;
|
if (parentModal) {
|
||||||
|
parentModal.allowFocusOverride = true;
|
||||||
|
parentModal.shouldHaveFocus = false;
|
||||||
|
}
|
||||||
|
wallpaperBrowser.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -915,7 +924,13 @@ Item {
|
|||||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||||
onFileSelected: (path) => {
|
onFileSelected: (path) => {
|
||||||
PortalService.setProfileImage(path);
|
PortalService.setProfileImage(path);
|
||||||
visible = false;
|
close();
|
||||||
|
}
|
||||||
|
onDialogClosed: {
|
||||||
|
if (parentModal) {
|
||||||
|
parentModal.allowFocusOverride = false;
|
||||||
|
parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,7 +943,13 @@ Item {
|
|||||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||||
onFileSelected: (path) => {
|
onFileSelected: (path) => {
|
||||||
SessionData.setWallpaper(path);
|
SessionData.setWallpaper(path);
|
||||||
visible = false;
|
close();
|
||||||
|
}
|
||||||
|
onDialogClosed: {
|
||||||
|
if (parentModal) {
|
||||||
|
parentModal.allowFocusOverride = false;
|
||||||
|
parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
@@ -8,13 +8,9 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
PanelWindow {
|
DankPopout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool batteryPopupVisible: false
|
|
||||||
property real triggerX: Screen.width - 380 - Theme.spacingL
|
|
||||||
property real triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingS
|
|
||||||
property real triggerWidth: 70
|
|
||||||
property string triggerSection: "right"
|
property string triggerSection: "right"
|
||||||
property var triggerScreen: null
|
property var triggerScreen: null
|
||||||
|
|
||||||
@@ -43,84 +39,22 @@ PanelWindow {
|
|||||||
ToastService.showError("Failed to set power profile")
|
ToastService.showError("Failed to set power profile")
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: batteryPopupVisible
|
popupWidth: 400
|
||||||
|
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 400
|
||||||
|
triggerX: Screen.width - 380 - Theme.spacingL
|
||||||
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingS
|
||||||
|
triggerWidth: 70
|
||||||
|
positioning: "center"
|
||||||
|
WlrLayershell.namespace: "quickshell-battery"
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
implicitWidth: 400
|
shouldBeVisible: false
|
||||||
implicitHeight: 300
|
visible: shouldBeVisible
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
|
||||||
WlrLayershell.exclusiveZone: -1
|
|
||||||
WlrLayershell.keyboardFocus: batteryPopupVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
left: true
|
|
||||||
right: true
|
|
||||||
bottom: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
content: Component {
|
||||||
anchors.fill: parent
|
Rectangle {
|
||||||
onClicked: function (mouse) {
|
id: batteryContent
|
||||||
var localPos = mapToItem(contentLoader, mouse.x, mouse.y)
|
|
||||||
if (localPos.x < 0 || localPos.x > contentLoader.width || localPos.y < 0
|
|
||||||
|| localPos.y > contentLoader.height)
|
|
||||||
batteryPopupVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: contentLoader
|
|
||||||
|
|
||||||
readonly property real screenWidth: root.screen ? root.screen.width : Screen.width
|
|
||||||
readonly property real screenHeight: root.screen ? root.screen.height : Screen.height
|
|
||||||
readonly property real targetWidth: Math.min(
|
|
||||||
380, screenWidth - Theme.spacingL * 2)
|
|
||||||
readonly property real calculatedX: {
|
|
||||||
var centerX = root.triggerX + (root.triggerWidth / 2) - (targetWidth / 2)
|
|
||||||
|
|
||||||
if (centerX >= Theme.spacingM
|
|
||||||
&& centerX + targetWidth <= screenWidth - Theme.spacingM) {
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerX < Theme.spacingM) {
|
|
||||||
return Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerX + targetWidth > screenWidth - Theme.spacingM) {
|
|
||||||
return screenWidth - targetWidth - Theme.spacingM
|
|
||||||
}
|
|
||||||
|
|
||||||
return centerX
|
|
||||||
}
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
active: batteryPopupVisible
|
|
||||||
width: targetWidth
|
|
||||||
height: item ? item.implicitHeight : 0
|
|
||||||
x: calculatedX
|
|
||||||
y: root.triggerY
|
|
||||||
opacity: batteryPopupVisible ? 1 : 0
|
|
||||||
scale: batteryPopupVisible ? 1 : 0.9
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: Rectangle {
|
|
||||||
implicitHeight: contentColumn.height + Theme.spacingL * 2
|
implicitHeight: contentColumn.height + Theme.spacingL * 2
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
@@ -129,22 +63,24 @@ PanelWindow {
|
|||||||
antialiasing: true
|
antialiasing: true
|
||||||
smooth: true
|
smooth: true
|
||||||
focus: true
|
focus: true
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (batteryPopupVisible)
|
if (root.shouldBeVisible)
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onPressed: function (event) {
|
Keys.onPressed: function (event) {
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
batteryPopupVisible = false
|
root.close()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onBatteryPopupVisibleChanged() {
|
function onShouldBeVisibleChanged() {
|
||||||
if (batteryPopupVisible)
|
if (root.shouldBeVisible)
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
parent.forceActiveFocus()
|
batteryContent.forceActiveFocus()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
target: root
|
target: root
|
||||||
@@ -220,8 +156,8 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
batteryPopupVisible = false
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -542,7 +478,7 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
root.setProfile(modelData)
|
root.setProfile(modelData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -599,4 +535,4 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0);
|
var globalPos = mapToGlobal(0, 0);
|
||||||
var currentScreen = parentScreen || Screen;
|
var currentScreen = parentScreen || Screen;
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
@@ -21,11 +21,9 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
z: 1000
|
acceptedButtons: Qt.LeftButton
|
||||||
preventStealing: true
|
|
||||||
propagateComposedEvents: false
|
|
||||||
|
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
@@ -39,15 +37,12 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: Qt.rgba(Theme.surfaceTextHover.r, Theme.surfaceTextHover.g, Theme.surfaceTextHover.b,
|
||||||
const baseColor = launcherArea.containsMouse
|
Theme.surfaceTextHover.a * Theme.widgetTransparency)
|
||||||
|| isActive ? Theme.surfaceTextPressed : Theme.surfaceTextHover
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b,
|
|
||||||
baseColor.a * Theme.widgetTransparency)
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemLogo {
|
SystemLogo {
|
||||||
visible: SettingsData.useOSLogo
|
visible: SettingsData.useOSLogo
|
||||||
@@ -67,11 +62,5 @@ Item {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ Rectangle {
|
|||||||
enabled: root.playerAvailable && root.opacity > 0 && root.width > 0 && textContainer.visible
|
enabled: root.playerAvailable && root.opacity > 0 && root.width > 0 && textContainer.visible
|
||||||
hoverEnabled: enabled
|
hoverEnabled: enabled
|
||||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (root.popupTarget && root.popupTarget.setTriggerPosition) {
|
if (root.popupTarget && root.popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = root.parentScreen || Screen
|
var currentScreen = root.parentScreen || Screen
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
@@ -617,7 +617,7 @@ PanelWindow {
|
|||||||
id: launcherButtonComponent
|
id: launcherButtonComponent
|
||||||
|
|
||||||
LauncherButton {
|
LauncherButton {
|
||||||
isActive: appDrawerLoader.item ? appDrawerLoader.item.isVisible : false
|
isActive: false
|
||||||
section: {
|
section: {
|
||||||
if (parent && parent.parent) {
|
if (parent && parent.parent) {
|
||||||
if (parent.parent === leftSection)
|
if (parent.parent === leftSection)
|
||||||
@@ -921,7 +921,7 @@ PanelWindow {
|
|||||||
id: batteryComponent
|
id: batteryComponent
|
||||||
|
|
||||||
Battery {
|
Battery {
|
||||||
batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.batteryPopupVisible : false
|
batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false
|
||||||
section: {
|
section: {
|
||||||
if (parent && parent.parent === leftSection)
|
if (parent && parent.parent === leftSection)
|
||||||
return "left"
|
return "left"
|
||||||
@@ -939,7 +939,7 @@ PanelWindow {
|
|||||||
onToggleBatteryPopup: {
|
onToggleBatteryPopup: {
|
||||||
batteryPopoutLoader.active = true
|
batteryPopoutLoader.active = true
|
||||||
if (batteryPopoutLoader.item) {
|
if (batteryPopoutLoader.item) {
|
||||||
batteryPopoutLoader.item.batteryPopupVisible = !batteryPopoutLoader.item.batteryPopupVisible
|
batteryPopoutLoader.item.toggle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -949,7 +949,7 @@ PanelWindow {
|
|||||||
id: controlCenterButtonComponent
|
id: controlCenterButtonComponent
|
||||||
|
|
||||||
ControlCenterButton {
|
ControlCenterButton {
|
||||||
isActive: controlCenterLoader.item ? controlCenterLoader.item.controlCenterVisible : false
|
isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false
|
||||||
section: {
|
section: {
|
||||||
if (parent && parent.parent === leftSection)
|
if (parent && parent.parent === leftSection)
|
||||||
return "left"
|
return "left"
|
||||||
@@ -968,8 +968,8 @@ PanelWindow {
|
|||||||
controlCenterLoader.active = true
|
controlCenterLoader.active = true
|
||||||
if (controlCenterLoader.item) {
|
if (controlCenterLoader.item) {
|
||||||
controlCenterLoader.item.triggerScreen = root.screen
|
controlCenterLoader.item.triggerScreen = root.screen
|
||||||
controlCenterLoader.item.controlCenterVisible = !controlCenterLoader.item.controlCenterVisible
|
controlCenterLoader.item.toggle()
|
||||||
if (controlCenterLoader.item.controlCenterVisible) {
|
if (controlCenterLoader.item.shouldBeVisible) {
|
||||||
if (NetworkService.wifiEnabled)
|
if (NetworkService.wifiEnabled)
|
||||||
NetworkService.scanWifi()
|
NetworkService.scanWifi()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popupTarget && popupTarget.setTriggerPosition) {
|
||||||
var globalPos = mapToGlobal(0, 0)
|
var globalPos = mapToGlobal(0, 0)
|
||||||
var currentScreen = parentScreen || Screen
|
var currentScreen = parentScreen || Screen
|
||||||
|
|||||||
156
Widgets/DankPopout.qml
Normal file
156
Widgets/DankPopout.qml
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import qs.Common
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias content: contentLoader.sourceComponent
|
||||||
|
property alias contentLoader: contentLoader
|
||||||
|
property real popupWidth: 400
|
||||||
|
property real popupHeight: 300
|
||||||
|
property real triggerX: 0
|
||||||
|
property real triggerY: 0
|
||||||
|
property real triggerWidth: 40
|
||||||
|
property string positioning: "center"
|
||||||
|
property int animationDuration: Theme.mediumDuration
|
||||||
|
property var animationEasing: Theme.emphasizedEasing
|
||||||
|
property bool shouldBeVisible: false
|
||||||
|
|
||||||
|
signal opened()
|
||||||
|
signal popoutClosed()
|
||||||
|
signal backgroundClicked()
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
closeTimer.stop();
|
||||||
|
shouldBeVisible = true;
|
||||||
|
visible = true;
|
||||||
|
opened();
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
shouldBeVisible = false;
|
||||||
|
closeTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if (shouldBeVisible)
|
||||||
|
close();
|
||||||
|
else
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: closeTimer
|
||||||
|
interval: animationDuration + 50
|
||||||
|
onTriggered: {
|
||||||
|
if (!shouldBeVisible) {
|
||||||
|
visible = false;
|
||||||
|
popoutClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
|
WlrLayershell.exclusiveZone: -1
|
||||||
|
WlrLayershell.keyboardFocus: shouldBeVisible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
bottom: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: shouldBeVisible
|
||||||
|
onClicked: (mouse) => {
|
||||||
|
var localPos = mapToItem(contentContainer, mouse.x, mouse.y);
|
||||||
|
if (localPos.x < 0 || localPos.x > contentContainer.width ||
|
||||||
|
localPos.y < 0 || localPos.y > contentContainer.height) {
|
||||||
|
backgroundClicked();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: contentContainer
|
||||||
|
|
||||||
|
readonly property real screenWidth: root.screen ? root.screen.width : 1920
|
||||||
|
readonly property real screenHeight: root.screen ? root.screen.height : 1080
|
||||||
|
readonly property real calculatedX: {
|
||||||
|
if (positioning === "center") {
|
||||||
|
var centerX = triggerX + (triggerWidth / 2) - (popupWidth / 2);
|
||||||
|
|
||||||
|
if (centerX >= Theme.spacingM && centerX + popupWidth <= screenWidth - Theme.spacingM)
|
||||||
|
return centerX;
|
||||||
|
|
||||||
|
if (centerX < Theme.spacingM)
|
||||||
|
return Theme.spacingM;
|
||||||
|
|
||||||
|
if (centerX + popupWidth > screenWidth - Theme.spacingM)
|
||||||
|
return screenWidth - popupWidth - Theme.spacingM;
|
||||||
|
|
||||||
|
return centerX;
|
||||||
|
} else if (positioning === "left") {
|
||||||
|
return Math.max(Theme.spacingM, triggerX);
|
||||||
|
} else if (positioning === "right") {
|
||||||
|
return Math.min(screenWidth - popupWidth - Theme.spacingM, triggerX + triggerWidth - popupWidth);
|
||||||
|
}
|
||||||
|
return triggerX;
|
||||||
|
}
|
||||||
|
readonly property real calculatedY: triggerY
|
||||||
|
|
||||||
|
width: popupWidth
|
||||||
|
height: popupHeight
|
||||||
|
x: calculatedX
|
||||||
|
y: calculatedY
|
||||||
|
opacity: shouldBeVisible ? 1 : 0
|
||||||
|
scale: shouldBeVisible ? 1 : 0.9
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: animationDuration
|
||||||
|
easing.type: animationEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: animationDuration
|
||||||
|
easing.type: animationEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: contentLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
active: root.visible
|
||||||
|
asynchronous: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: shouldBeVisible
|
||||||
|
focus: shouldBeVisible
|
||||||
|
|
||||||
|
Keys.onEscapePressed: (event) => {
|
||||||
|
close();
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
Qt.callLater(function() {
|
||||||
|
forceActiveFocus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
shell.qml
20
shell.qml
@@ -52,12 +52,13 @@ ShellRoot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
Loader {
|
||||||
id: centcomPopoutLoader
|
id: centcomPopoutLoader
|
||||||
active: false
|
active: false
|
||||||
|
sourceComponent: Component {
|
||||||
CentcomPopout {
|
CentcomPopout {
|
||||||
id: centcomPopout
|
id: centcomPopout
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,10 +107,7 @@ ShellRoot {
|
|||||||
onPowerActionRequested: (action, title, message) => {
|
onPowerActionRequested: (action, title, message) => {
|
||||||
powerConfirmModalLoader.active = true
|
powerConfirmModalLoader.active = true
|
||||||
if (powerConfirmModalLoader.item) {
|
if (powerConfirmModalLoader.item) {
|
||||||
powerConfirmModalLoader.item.powerConfirmAction = action
|
powerConfirmModalLoader.item.show(action, title, message)
|
||||||
powerConfirmModalLoader.item.powerConfirmTitle = title
|
|
||||||
powerConfirmModalLoader.item.powerConfirmMessage = message
|
|
||||||
powerConfirmModalLoader.item.powerConfirmVisible = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onLockRequested: {
|
onLockRequested: {
|
||||||
@@ -151,6 +149,12 @@ ShellRoot {
|
|||||||
|
|
||||||
PowerMenu {
|
PowerMenu {
|
||||||
id: powerMenu
|
id: powerMenu
|
||||||
|
onPowerActionRequested: (action, title, message) => {
|
||||||
|
powerConfirmModalLoader.active = true
|
||||||
|
if (powerConfirmModalLoader.item) {
|
||||||
|
powerConfirmModalLoader.item.show(action, title, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user