mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-05-03 02:52:07 -04:00
Compare commits
9 Commits
v1.4.3
...
64c9222000
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64c9222000 | ||
|
|
12acf2dd51 | ||
|
|
fea97b4aad | ||
|
|
c6d398eeac | ||
|
|
7a74be83d7 | ||
|
|
67a6427418 | ||
|
|
18b20d3225 | ||
|
|
8a76885fb6 | ||
|
|
69b1e61ab7 |
@@ -5,5 +5,6 @@ const (
|
||||
dbusPath = "/org/freedesktop/login1"
|
||||
dbusManagerInterface = "org.freedesktop.login1.Manager"
|
||||
dbusSessionInterface = "org.freedesktop.login1.Session"
|
||||
dbusUserInterface = "org.freedesktop.login1.User"
|
||||
dbusPropsInterface = "org.freedesktop.DBus.Properties"
|
||||
)
|
||||
|
||||
@@ -17,15 +17,8 @@ func NewManager() (*Manager, error) {
|
||||
return nil, fmt.Errorf("failed to connect to system bus: %w", err)
|
||||
}
|
||||
|
||||
sessionID := os.Getenv("XDG_SESSION_ID")
|
||||
if sessionID == "" {
|
||||
sessionID = "self"
|
||||
}
|
||||
|
||||
m := &Manager{
|
||||
state: &SessionState{
|
||||
SessionID: sessionID,
|
||||
},
|
||||
state: &SessionState{},
|
||||
stateMutex: sync.RWMutex{},
|
||||
|
||||
stopChan: make(chan struct{}),
|
||||
@@ -60,12 +53,13 @@ func (m *Manager) initialize() error {
|
||||
|
||||
m.initializeFallbackDelay()
|
||||
|
||||
sessionPath, err := m.getSession(m.state.SessionID)
|
||||
sessionID, sessionPath, err := m.discoverSession()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get session path: %w", err)
|
||||
}
|
||||
|
||||
m.stateMutex.Lock()
|
||||
m.state.SessionID = sessionID
|
||||
m.state.SessionPath = string(sessionPath)
|
||||
m.sessionPath = sessionPath
|
||||
m.stateMutex.Unlock()
|
||||
@@ -79,6 +73,41 @@ func (m *Manager) initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) discoverSession() (string, dbus.ObjectPath, error) {
|
||||
// 1. Explicit XDG_SESSION_ID
|
||||
if id := os.Getenv("XDG_SESSION_ID"); id != "" {
|
||||
if path, err := m.getSession(id); err == nil {
|
||||
fmt.Fprintf(os.Stderr, "loginctl: using XDG_SESSION_ID=%s\n", id)
|
||||
return id, path, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 2. PID-based lookup (works when caller is inside a session cgroup)
|
||||
if id, path, err := m.getSessionByPID(uint32(os.Getpid())); err == nil {
|
||||
fmt.Fprintf(os.Stderr, "loginctl: found session %s via PID\n", id)
|
||||
return id, path, nil
|
||||
}
|
||||
|
||||
// 3. User's primary display session (handles UWSM and similar)
|
||||
if id, path, err := m.getUserDisplaySession(); err == nil {
|
||||
fmt.Fprintf(os.Stderr, "loginctl: found session %s via User.Display\n", id)
|
||||
return id, path, nil
|
||||
}
|
||||
|
||||
// 4. Score all sessions for current UID
|
||||
if id, path, err := m.findBestSession(); err == nil {
|
||||
fmt.Fprintf(os.Stderr, "loginctl: found session %s via ListSessions scoring\n", id)
|
||||
return id, path, nil
|
||||
}
|
||||
|
||||
// 5. Last resort: "self"
|
||||
path, err := m.getSession("self")
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("%w", err)
|
||||
}
|
||||
return "self", path, nil
|
||||
}
|
||||
|
||||
func (m *Manager) getSession(id string) (dbus.ObjectPath, error) {
|
||||
var out dbus.ObjectPath
|
||||
err := m.managerObj.Call(dbusManagerInterface+".GetSession", 0, id).Store(&out)
|
||||
@@ -88,6 +117,166 @@ func (m *Manager) getSession(id string) (dbus.ObjectPath, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (m *Manager) getSessionByPID(pid uint32) (string, dbus.ObjectPath, error) {
|
||||
var path dbus.ObjectPath
|
||||
if err := m.managerObj.Call(dbusManagerInterface+".GetSessionByPID", 0, pid).Store(&path); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
sessionObj := m.conn.Object(dbusDest, path)
|
||||
var id dbus.Variant
|
||||
if err := sessionObj.Call(dbusPropsInterface+".Get", 0, dbusSessionInterface, "Id").Store(&id); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return id.Value().(string), path, nil
|
||||
}
|
||||
|
||||
func (m *Manager) getUserDisplaySession() (string, dbus.ObjectPath, error) {
|
||||
uid := uint32(os.Getuid())
|
||||
|
||||
var userPath dbus.ObjectPath
|
||||
if err := m.managerObj.Call(dbusManagerInterface+".GetUser", 0, uid).Store(&userPath); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
userObj := m.conn.Object(dbusDest, userPath)
|
||||
var display dbus.Variant
|
||||
if err := userObj.Call(dbusPropsInterface+".Get", 0, dbusUserInterface, "Display").Store(&display); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
pair, ok := display.Value().([]any)
|
||||
if !ok || len(pair) < 2 {
|
||||
return "", "", fmt.Errorf("unexpected Display format")
|
||||
}
|
||||
|
||||
sessionID, _ := pair[0].(string)
|
||||
sessionPath, _ := pair[1].(dbus.ObjectPath)
|
||||
if sessionID == "" || sessionPath == "" {
|
||||
return "", "", fmt.Errorf("empty Display session")
|
||||
}
|
||||
|
||||
return sessionID, sessionPath, nil
|
||||
}
|
||||
|
||||
type sessionCandidate struct {
|
||||
id string
|
||||
path dbus.ObjectPath
|
||||
}
|
||||
|
||||
func (m *Manager) findBestSession() (string, dbus.ObjectPath, error) {
|
||||
// ListSessions returns a(susso): [][]any where each entry is [id, uid, name, seat, path]
|
||||
var raw [][]any
|
||||
if err := m.managerObj.Call(dbusManagerInterface+".ListSessions", 0).Store(&raw); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
uid := uint32(os.Getuid())
|
||||
var candidates []sessionCandidate
|
||||
for _, entry := range raw {
|
||||
if len(entry) < 5 {
|
||||
continue
|
||||
}
|
||||
entryUID, _ := entry[1].(uint32)
|
||||
if entryUID != uid {
|
||||
continue
|
||||
}
|
||||
id, _ := entry[0].(string)
|
||||
path, _ := entry[4].(dbus.ObjectPath)
|
||||
if id != "" && path != "" {
|
||||
candidates = append(candidates, sessionCandidate{id: id, path: path})
|
||||
}
|
||||
}
|
||||
if len(candidates) == 0 {
|
||||
return "", "", fmt.Errorf("no sessions for uid %d", uid)
|
||||
}
|
||||
|
||||
bestScore := -1
|
||||
var best sessionCandidate
|
||||
for _, c := range candidates {
|
||||
score := m.scoreSession(c.path)
|
||||
if score > bestScore {
|
||||
bestScore = score
|
||||
best = c
|
||||
}
|
||||
}
|
||||
if bestScore < 0 {
|
||||
return "", "", fmt.Errorf("no viable session found")
|
||||
}
|
||||
return best.id, best.path, nil
|
||||
}
|
||||
|
||||
func (m *Manager) scoreSession(path dbus.ObjectPath) int {
|
||||
obj := m.conn.Object(dbusDest, path)
|
||||
var props map[string]dbus.Variant
|
||||
if err := obj.Call(dbusPropsInterface+".GetAll", 0, dbusSessionInterface).Store(&props); err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
getStr := func(key string) string {
|
||||
if v, ok := props[key]; ok {
|
||||
if s, ok := v.Value().(string); ok {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
getBool := func(key string) bool {
|
||||
if v, ok := props[key]; ok {
|
||||
if b, ok := v.Value().(bool); ok {
|
||||
return b
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
getUint32 := func(key string) uint32 {
|
||||
if v, ok := props[key]; ok {
|
||||
if u, ok := v.Value().(uint32); ok {
|
||||
return u
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
class := getStr("Class")
|
||||
if class != "user" {
|
||||
return -1
|
||||
}
|
||||
if getBool("Remote") {
|
||||
return -1
|
||||
}
|
||||
|
||||
score := 0
|
||||
|
||||
if getBool("Active") {
|
||||
score += 100
|
||||
}
|
||||
|
||||
switch getStr("Type") {
|
||||
case "wayland", "x11":
|
||||
score += 80
|
||||
case "tty":
|
||||
score += 10
|
||||
}
|
||||
|
||||
if v, ok := props["Seat"]; ok {
|
||||
if seatArr, ok := v.Value().([]any); ok && len(seatArr) >= 1 {
|
||||
if seat, ok := seatArr[0].(string); ok && seat != "" {
|
||||
score += 40
|
||||
if seat == "seat0" {
|
||||
score += 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if getUint32("VTNr") > 0 {
|
||||
score += 20
|
||||
}
|
||||
|
||||
return score
|
||||
}
|
||||
|
||||
func (m *Manager) refreshSessionBinding() error {
|
||||
if m.managerObj == nil || m.conn == nil {
|
||||
return fmt.Errorf("manager not fully initialized")
|
||||
|
||||
@@ -41,6 +41,12 @@ BasePill {
|
||||
return `${id}::${tooltipTitle}`;
|
||||
}
|
||||
|
||||
// ! TODO - replace with either native dbus client (like plugins use) or just a DMS cli or something
|
||||
function callContextMenuFallback(trayItemId, globalX, globalY) {
|
||||
const script = ['ITEMS=$(dbus-send --session --print-reply --dest=org.kde.StatusNotifierWatcher /StatusNotifierWatcher org.freedesktop.DBus.Properties.Get string:org.kde.StatusNotifierWatcher string:RegisteredStatusNotifierItems 2>/dev/null)', 'while IFS= read -r line; do', ' line="${line#*\\\"}"', ' line="${line%\\\"*}"', ' [ -z "$line" ] && continue', ' BUS="${line%%/*}"', ' OBJ="/${line#*/}"', ' ID=$(dbus-send --session --print-reply --dest="$BUS" "$OBJ" org.freedesktop.DBus.Properties.Get string:org.kde.StatusNotifierItem string:Id 2>/dev/null | grep -oP "(?<=\\\")(.*?)(?=\\\")" | tail -1)', ' if [ "$ID" = "$1" ]; then', ' dbus-send --session --type=method_call --dest="$BUS" "$OBJ" org.kde.StatusNotifierItem.ContextMenu int32:"$2" int32:"$3"', ' exit 0', ' fi', 'done <<< "$ITEMS"',].join("\n");
|
||||
Quickshell.execDetached(["bash", "-c", script, "_", trayItemId, String(globalX), String(globalY)]);
|
||||
}
|
||||
|
||||
property int _trayOrderTrigger: 0
|
||||
|
||||
Connections {
|
||||
@@ -380,8 +386,11 @@ BasePill {
|
||||
return;
|
||||
if (mouse.button !== Qt.RightButton)
|
||||
return;
|
||||
if (!delegateRoot.trayItem?.hasMenu)
|
||||
if (!delegateRoot.trayItem?.hasMenu) {
|
||||
const gp = trayItemArea.mapToGlobal(mouse.x, mouse.y);
|
||||
root.callContextMenuFallback(delegateRoot.trayItem.id, Math.round(gp.x), Math.round(gp.y));
|
||||
return;
|
||||
}
|
||||
root.menuOpen = false;
|
||||
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVerticalOrientation, root.axis);
|
||||
}
|
||||
@@ -637,8 +646,11 @@ BasePill {
|
||||
return;
|
||||
if (mouse.button !== Qt.RightButton)
|
||||
return;
|
||||
if (!delegateRoot.trayItem?.hasMenu)
|
||||
if (!delegateRoot.trayItem?.hasMenu) {
|
||||
const gp = trayItemArea.mapToGlobal(mouse.x, mouse.y);
|
||||
root.callContextMenuFallback(delegateRoot.trayItem.id, Math.round(gp.x), Math.round(gp.y));
|
||||
return;
|
||||
}
|
||||
root.menuOpen = false;
|
||||
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVerticalOrientation, root.axis);
|
||||
}
|
||||
@@ -1065,9 +1077,11 @@ BasePill {
|
||||
root.menuOpen = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!trayItem.hasMenu)
|
||||
if (!trayItem.hasMenu) {
|
||||
const gp = itemArea.mapToGlobal(mouse.x, mouse.y);
|
||||
root.callContextMenuFallback(trayItem.id, Math.round(gp.x), Math.round(gp.y));
|
||||
return;
|
||||
}
|
||||
root.showForTrayItem(trayItem, menuContainer, parentScreen, root.isAtBottom, root.isVerticalOrientation, root.axis);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,11 @@ Singleton {
|
||||
property string lockDateFormat: ""
|
||||
property bool lockScreenShowPowerActions: true
|
||||
property bool lockScreenShowProfileImage: true
|
||||
property bool powerActionConfirm: true
|
||||
property real powerActionHoldDuration: 0.5
|
||||
property var powerMenuActions: ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]
|
||||
property string powerMenuDefaultAction: "logout"
|
||||
property bool powerMenuGridLayout: false
|
||||
property var screenPreferences: ({})
|
||||
property int animationSpeed: 2
|
||||
property string wallpaperFillMode: "Fill"
|
||||
@@ -75,6 +80,11 @@ Singleton {
|
||||
lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : "";
|
||||
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true;
|
||||
lockScreenShowProfileImage = settings.lockScreenShowProfileImage !== undefined ? settings.lockScreenShowProfileImage : true;
|
||||
powerActionConfirm = settings.powerActionConfirm !== undefined ? settings.powerActionConfirm : true;
|
||||
powerActionHoldDuration = settings.powerActionHoldDuration !== undefined ? settings.powerActionHoldDuration : 0.5;
|
||||
powerMenuActions = settings.powerMenuActions !== undefined ? settings.powerMenuActions : ["reboot", "logout", "poweroff", "lock", "suspend", "restart"];
|
||||
powerMenuDefaultAction = settings.powerMenuDefaultAction !== undefined ? settings.powerMenuDefaultAction : "logout";
|
||||
powerMenuGridLayout = settings.powerMenuGridLayout !== undefined ? settings.powerMenuGridLayout : false;
|
||||
screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({});
|
||||
animationSpeed = settings.animationSpeed !== undefined ? settings.animationSpeed : 2;
|
||||
wallpaperFillMode = settings.wallpaperFillMode !== undefined ? settings.wallpaperFillMode : "Fill";
|
||||
|
||||
@@ -1231,6 +1231,12 @@ Item {
|
||||
LockPowerMenu {
|
||||
id: powerMenu
|
||||
showLogout: false
|
||||
powerActionConfirmOverride: GreetdSettings.powerActionConfirm
|
||||
powerActionHoldDurationOverride: GreetdSettings.powerActionHoldDuration
|
||||
powerMenuActionsOverride: GreetdSettings.powerMenuActions
|
||||
powerMenuDefaultActionOverride: GreetdSettings.powerMenuDefaultAction
|
||||
powerMenuGridLayoutOverride: GreetdSettings.powerMenuGridLayout
|
||||
requiredActions: ["poweroff"]
|
||||
onClosed: {
|
||||
if (isPrimaryScreen && inputField && inputField.forceActiveFocus) {
|
||||
Qt.callLater(() => inputField.forceActiveFocus());
|
||||
|
||||
@@ -24,13 +24,20 @@ Rectangle {
|
||||
property real holdProgress: 0
|
||||
property bool showHoldHint: false
|
||||
|
||||
readonly property bool needsConfirmation: SettingsData.powerActionConfirm
|
||||
readonly property int holdDurationMs: SettingsData.powerActionHoldDuration * 1000
|
||||
property var powerActionConfirmOverride: undefined
|
||||
property var powerActionHoldDurationOverride: undefined
|
||||
property var powerMenuActionsOverride: undefined
|
||||
property var powerMenuDefaultActionOverride: undefined
|
||||
property var powerMenuGridLayoutOverride: undefined
|
||||
property var requiredActions: []
|
||||
|
||||
readonly property bool needsConfirmation: powerActionConfirmOverride !== undefined ? powerActionConfirmOverride : SettingsData.powerActionConfirm
|
||||
readonly property int holdDurationMs: (powerActionHoldDurationOverride !== undefined ? powerActionHoldDurationOverride : SettingsData.powerActionHoldDuration) * 1000
|
||||
|
||||
signal closed
|
||||
|
||||
function updateVisibleActions() {
|
||||
const allActions = (typeof SettingsData !== "undefined" && SettingsData.powerMenuActions) ? SettingsData.powerMenuActions : ["logout", "suspend", "hibernate", "reboot", "poweroff"];
|
||||
const allActions = powerMenuActionsOverride !== undefined ? powerMenuActionsOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuActions) ? SettingsData.powerMenuActions : ["logout", "suspend", "hibernate", "reboot", "poweroff"]);
|
||||
const hibernateSupported = (typeof SessionService !== "undefined" && SessionService.hibernateSupported) || false;
|
||||
let filtered = allActions.filter(action => {
|
||||
if (action === "hibernate" && !hibernateSupported)
|
||||
@@ -44,9 +51,14 @@ Rectangle {
|
||||
return true;
|
||||
});
|
||||
|
||||
for (const action of requiredActions) {
|
||||
if (!filtered.includes(action))
|
||||
filtered.push(action);
|
||||
}
|
||||
|
||||
visibleActions = filtered;
|
||||
|
||||
useGridLayout = (typeof SettingsData !== "undefined" && SettingsData.powerMenuGridLayout !== undefined) ? SettingsData.powerMenuGridLayout : false;
|
||||
useGridLayout = powerMenuGridLayoutOverride !== undefined ? powerMenuGridLayoutOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuGridLayout !== undefined) ? SettingsData.powerMenuGridLayout : false);
|
||||
if (!useGridLayout)
|
||||
return;
|
||||
const count = visibleActions.length;
|
||||
@@ -73,7 +85,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
function getDefaultActionIndex() {
|
||||
const defaultAction = (typeof SettingsData !== "undefined" && SettingsData.powerMenuDefaultAction) ? SettingsData.powerMenuDefaultAction : "suspend";
|
||||
const defaultAction = powerMenuDefaultActionOverride !== undefined ? powerMenuDefaultActionOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuDefaultAction) ? SettingsData.powerMenuDefaultAction : "suspend");
|
||||
const index = visibleActions.indexOf(defaultAction);
|
||||
return index >= 0 ? index : 0;
|
||||
}
|
||||
@@ -780,8 +792,9 @@ Rectangle {
|
||||
}
|
||||
|
||||
StyledText {
|
||||
readonly property real totalMs: SettingsData.powerActionHoldDuration * 1000
|
||||
readonly property real totalMs: root.holdDurationMs
|
||||
readonly property int remainingMs: Math.ceil(totalMs * (1 - root.holdProgress))
|
||||
readonly property real durationSec: root.holdDurationMs / 1000
|
||||
text: {
|
||||
if (root.showHoldHint)
|
||||
return I18n.tr("Hold longer to confirm");
|
||||
@@ -792,7 +805,7 @@ Rectangle {
|
||||
}
|
||||
if (totalMs < 1000)
|
||||
return I18n.tr("Hold to confirm (%1 ms)").arg(totalMs);
|
||||
return I18n.tr("Hold to confirm (%1s)").arg(SettingsData.powerActionHoldDuration);
|
||||
return I18n.tr("Hold to confirm (%1s)").arg(durationSec);
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
|
||||
|
||||
@@ -351,6 +351,7 @@ Item {
|
||||
Loader {
|
||||
id: contentLoader
|
||||
anchors.fill: parent
|
||||
active: root.widgetEnabled && root.activeComponent !== null
|
||||
sourceComponent: root.activeComponent
|
||||
|
||||
function reloadComponent() {
|
||||
|
||||
@@ -56,8 +56,8 @@ Singleton {
|
||||
}
|
||||
readonly property bool isCharging: batteryAvailable && batteries.some(b => b.state === UPowerDeviceState.Charging)
|
||||
|
||||
// Is the system plugged in (none of the batteries are discharging or empty)
|
||||
readonly property bool isPluggedIn: batteryAvailable && batteries.every(b => b.state !== UPowerDeviceState.Discharging)
|
||||
// Is the system plugged in (Is not running on battery)
|
||||
readonly property bool isPluggedIn: !UPower.onBattery
|
||||
readonly property bool isLowBattery: batteryAvailable && batteryLevel <= 20
|
||||
|
||||
onIsPluggedInChanged: {
|
||||
|
||||
@@ -259,7 +259,7 @@ Singleton {
|
||||
const terminal = Quickshell.env("TERMINAL") || "xterm";
|
||||
|
||||
if (SettingsData.updaterUseCustomCommand && SettingsData.updaterCustomCommand.length > 0) {
|
||||
const updateCommand = `${SettingsData.updaterCustomCommand} && echo "Updates complete! Press Enter to close..." && read`;
|
||||
const updateCommand = `${SettingsData.updaterCustomCommand} && echo -n "Updates complete! " ; echo "Press Enter to close..." && read`;
|
||||
const termClass = SettingsData.updaterTerminalAdditionalParams;
|
||||
|
||||
var finalCommand = [terminal];
|
||||
@@ -274,7 +274,7 @@ Singleton {
|
||||
} else {
|
||||
const params = packageManagerParams[pkgManager].upgradeSettings.params.join(" ");
|
||||
const sudo = packageManagerParams[pkgManager].upgradeSettings.requiresSudo ? "sudo" : "";
|
||||
const updateCommand = `${sudo} ${pkgManager} ${params} && echo "Updates complete! Press Enter to close..." && read`;
|
||||
const updateCommand = `${sudo} ${pkgManager} ${params} && echo -n "Updates complete! " ; echo "Press Enter to close..." && read`;
|
||||
|
||||
updater.command = [terminal, "-e", "sh", "-c", updateCommand];
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.4.3
|
||||
v1.4.4
|
||||
|
||||
@@ -289,7 +289,7 @@ Item {
|
||||
visible: false
|
||||
color: "transparent"
|
||||
Component.onCompleted: {
|
||||
if (typeof updatesEnabled !== "undefined")
|
||||
if (typeof updatesEnabled !== "undefined" && !root.overlayContent)
|
||||
updatesEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user