1091 lines
41 KiB
QML
1091 lines
41 KiB
QML
// Lucid bar from Sn3akyy1/lucid at bdd7f79da18efd837f79dcecbe5d2ec178abc10c (MIT).
|
|||
|
|
// Kept as a separate component so the other Lucid surfaces stay optional.
|
||
|
|
import "./lucidbar"
|
||
|
|
import "./lucidedit"
|
||
|
|
import QtQuick
|
||
|
|
import Quickshell
|
||
|
|
import Quickshell.Io
|
||
|
|
import Quickshell.Wayland
|
||
|
|
import qs
|
||
|
|
|
||
|
|
Variants {
|
||
|
|
id: bars
|
||
|
|
property var dock
|
||
|
|
property var toastMod: null
|
||
|
|
|
||
|
|
model: Monitors.barEverywhere ? Quickshell.screens : [""]
|
||
|
|
|
||
|
|
PanelWindow {
|
||
|
|
id: bar
|
||
|
|
|
||
|
|
// a display from Quickshell.screens with a bar on every one, or "" for the one bar
|
||
|
|
required property var modelData
|
||
|
|
// the bar that speaks for the shell: it alone turns into notification
|
||
|
|
// popups, raises the privacy toast and answers the modules' ipc
|
||
|
|
readonly property bool primary: !Monitors.barEverywhere || bar.screen === Monitors.popupScreen
|
||
|
|
// what the shell's ipc targets reach on the main bar
|
||
|
|
readonly property var clockModule: clockMod
|
||
|
|
readonly property var mprisModule: mprisMod
|
||
|
|
readonly property var workspacesModule: workspacesMod
|
||
|
|
|
||
|
|
PaletteFade {
|
||
|
|
active: bar.visible
|
||
|
|
}
|
||
|
|
|
||
|
|
// the display Settings > Displays picks, or this one's own. gated,
|
||
|
|
// because unset must leave the choice to hyprland, which null would not
|
||
|
|
Binding {
|
||
|
|
target: bar
|
||
|
|
property: "screen"
|
||
|
|
value: bar.modelData !== "" ? bar.modelData : Monitors.barPlacement
|
||
|
|
when: bar.modelData !== "" || Monitors.barPlacement !== null
|
||
|
|
}
|
||
|
|
|
||
|
|
visible: Prefs.loaded && Prefs.barEnabled && Monitors.surfacesUp
|
||
|
|
property bool laidOut: false
|
||
|
|
// stand-ins take room in edit mode, so this asks after the modules themselves
|
||
|
|
readonly property bool anyModuleShown: Prefs.barZones.some((zone) => {
|
||
|
|
return bar.zoneKeys(zone).some((key) => {
|
||
|
|
return bar.realWidthOf(key) > 0.5;
|
||
|
|
});
|
||
|
|
})
|
||
|
|
// edit mode: the module in hand, how far it sits off its slot, and the
|
||
|
|
// arrangement the bar shows while it is held
|
||
|
|
property real editT: Edit.active ? 1 : 0
|
||
|
|
// in edit mode the modules part a little, so each gap has room for its clasp
|
||
|
|
readonly property real editGap: Theme.dp(16) * bar.editT
|
||
|
|
property string dragKey: ""
|
||
|
|
property real dragShift: 0
|
||
|
|
property real dragLift: 0
|
||
|
|
property var dragGroups: null
|
||
|
|
property bool dragHeld: false
|
||
|
|
|
||
|
|
Behavior on editT {
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barMs(320)
|
||
|
|
easing.type: Easing.OutCubic
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
function xOf(key) {
|
||
|
|
return bar.placeFor(key) + (key === bar.dragKey ? bar.dragShift : 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
function liftOf(key) {
|
||
|
|
return key === bar.dragKey ? bar.dragLift : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// a right click on a module: its sheet, on the side of the screen away from it
|
||
|
|
function editModule(key) {
|
||
|
|
const mod = bar.pillFor[key];
|
||
|
|
const cx = bar.xOf(key) + (mod ? mod.width : 0) / 2;
|
||
|
|
Edit.openSheet("module", key, Edit.sideFor(cx, bar.width), bar.screen ? bar.screen.name : "");
|
||
|
|
}
|
||
|
|
|
||
|
|
// the sheet's open button: this bar's module opens as a click would open it
|
||
|
|
Connections {
|
||
|
|
function onModuleOpenRequested(id, screen) {
|
||
|
|
if (screen !== "" ? (!bar.screen || bar.screen.name !== screen) : !bar.primary)
|
||
|
|
return ;
|
||
|
|
|
||
|
|
const mod = bar.pillFor[id];
|
||
|
|
if (!mod)
|
||
|
|
return ;
|
||
|
|
|
||
|
|
if (id === "start") {
|
||
|
|
dock.openLauncher("");
|
||
|
|
} else if (id === "media") {
|
||
|
|
mod.openPanel("player");
|
||
|
|
} else {
|
||
|
|
if (mod.compactClicked)
|
||
|
|
mod.compactClicked();
|
||
|
|
|
||
|
|
mod.expanded = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
target: Edit
|
||
|
|
}
|
||
|
|
|
||
|
|
// keys, when given, lets modules joined to the next one sit flush against it
|
||
|
|
function placeGroup(widths, originX, keys) {
|
||
|
|
const gap = Theme.dp(Prefs.barSpacing) + bar.editGap;
|
||
|
|
const out = [];
|
||
|
|
let x = originX;
|
||
|
|
let any = false;
|
||
|
|
let trailing = 0;
|
||
|
|
for (let i = 0; i < widths.length; i++) {
|
||
|
|
out.push(x);
|
||
|
|
const w = widths[i];
|
||
|
|
if (w > 0.5) {
|
||
|
|
trailing = keys && bar.joinedAfter(keys, widths, i) ? 0 : (gap > 0 ? gap * Math.min(1, w / gap) : 0);
|
||
|
|
x += w + trailing;
|
||
|
|
any = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
out.push(any ? Math.max(originX, x - trailing) : originX);
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
// whether the module at i is joined to the one right after it. both
|
||
|
|
// have to be in the bar this moment: one that has emptied out (a tray
|
||
|
|
// with no icons, workspaces off in the overview) parts its group there
|
||
|
|
function joinedAfter(keys, widths, i) {
|
||
|
|
return i + 1 < keys.length && widths[i] > 0.5 && widths[i + 1] > 0.5 && bar.realWidthOf(keys[i]) > 0.5 && bar.realWidthOf(keys[i + 1]) > 0.5 && Prefs.barJoinedNow(keys[i], keys[i + 1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// what a module's pill reads to square off the corners it shares
|
||
|
|
function joinedLeftOf(key) {
|
||
|
|
const at = bar.placeMap[key];
|
||
|
|
if (!at || at.at === 0)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
const keys = bar.zoneKeys(at.zone);
|
||
|
|
return bar.realWidthOf(key) > 0.5 && bar.realWidthOf(keys[at.at - 1]) > 0.5 && Prefs.barJoinedNow(keys[at.at - 1], key);
|
||
|
|
}
|
||
|
|
|
||
|
|
function joinedRightOf(key) {
|
||
|
|
const at = bar.placeMap[key];
|
||
|
|
if (!at)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
const keys = bar.zoneKeys(at.zone);
|
||
|
|
return at.at + 1 < keys.length && bar.realWidthOf(key) > 0.5 && bar.realWidthOf(keys[at.at + 1]) > 0.5 && Prefs.barJoinedNow(key, keys[at.at + 1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// per module key, radius caps where a hanging panel meets the islands: {corners, tops, sides, fillets}
|
||
|
|
readonly property var hangPlan: bar.planHangs()
|
||
|
|
|
||
|
|
function surfaceSpan(mod) {
|
||
|
|
const l = mod.x + (mod.surfaceX !== undefined ? mod.surfaceX : 0);
|
||
|
|
return [l, l + (mod.surfaceWidth !== undefined ? mod.surfaceWidth : mod.width)];
|
||
|
|
}
|
||
|
|
|
||
|
|
function planHangs() {
|
||
|
|
const plan = ({
|
||
|
|
"corners": ({}),
|
||
|
|
"tops": ({}),
|
||
|
|
"sides": ({}),
|
||
|
|
"fillets": []
|
||
|
|
});
|
||
|
|
const popups = Prefs.barPopupMode;
|
||
|
|
if (popups && !Prefs.barPopupNotched)
|
||
|
|
return plan;
|
||
|
|
|
||
|
|
const most = Theme.dp(Prefs.barNotchFlare);
|
||
|
|
const bite = 0.5;
|
||
|
|
const cap = (key, corner, v) => {
|
||
|
|
const c = plan.corners[key] || (plan.corners[key] = ({}));
|
||
|
|
c[corner] = Math.min(c[corner] === undefined ? 1e6 : c[corner], Math.max(0, v));
|
||
|
|
};
|
||
|
|
const fillet = (x, y, size, mirrored, flipped) => {
|
||
|
|
if (size >= 1)
|
||
|
|
plan.fillets.push({ "x": x, "y": y, "size": size, "mirrored": mirrored, "flipped": flipped });
|
||
|
|
|
||
|
|
};
|
||
|
|
// islands: runs of joined modules as they stand
|
||
|
|
const islands = [];
|
||
|
|
const shelves = [];
|
||
|
|
for (const zone of Prefs.barZones) {
|
||
|
|
const keys = bar.zoneKeys(zone);
|
||
|
|
let run = null;
|
||
|
|
for (let i = 0; i < keys.length; i++) {
|
||
|
|
const mod = bar.pillFor[keys[i]];
|
||
|
|
if (!mod || bar.widthOf(keys[i]) <= 0.5) {
|
||
|
|
run = null;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (run && Prefs.barJoinedNow(keys[i - 1], keys[i])) {
|
||
|
|
run.keys.push(keys[i]);
|
||
|
|
run.r = bar.surfaceSpan(mod)[1];
|
||
|
|
} else {
|
||
|
|
run = ({ "keys": [keys[i]], "l": bar.surfaceSpan(mod)[0], "r": bar.surfaceSpan(mod)[1], "top": mod.y, "bottom": mod.y + mod.compactHeight });
|
||
|
|
islands.push(run);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// what hangs: a notched pop-up, or a joined module opened in place
|
||
|
|
for (const isle of islands) {
|
||
|
|
for (let j = 0; j < isle.keys.length; j++) {
|
||
|
|
const m = bar.pillFor[isle.keys[j]];
|
||
|
|
if (popups) {
|
||
|
|
const pop = m.notchedPopup === true && m.popupOpen ? m.popupItem : null;
|
||
|
|
if (pop && pop.height > 0.5)
|
||
|
|
shelves.push({ "key": isle.keys[j], "l": m.x + pop.x, "r": m.x + pop.x + pop.width, "y": m.y + pop.y, "depth": pop.height });
|
||
|
|
|
||
|
|
} else if (isle.keys.length > 1 && m !== workspacesMod && m.height - m.compactHeight > 0.5) {
|
||
|
|
const depth = m.height - m.compactHeight;
|
||
|
|
const side = ({});
|
||
|
|
if (j > 0) {
|
||
|
|
const run = m.x - isle.l;
|
||
|
|
const f = Math.floor(Math.min(most, run / 2, depth / 2));
|
||
|
|
fillet(m.x - f + bite, isle.bottom - bite, f, false, false);
|
||
|
|
cap(isle.keys[0], "bl", run - f);
|
||
|
|
side.bl = depth - f;
|
||
|
|
}
|
||
|
|
if (j < isle.keys.length - 1) {
|
||
|
|
const run = isle.r - (m.x + m.width);
|
||
|
|
const f = Math.floor(Math.min(most, run / 2, depth / 2));
|
||
|
|
fillet(m.x + m.width - bite, isle.bottom - bite, f, true, false);
|
||
|
|
cap(isle.keys[isle.keys.length - 1], "br", run - f);
|
||
|
|
side.br = depth - f;
|
||
|
|
}
|
||
|
|
plan.sides[isle.keys[j]] = side;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// a pop-up's top is the screen edge upside down: islands stand on it or it hangs from them
|
||
|
|
for (const shelf of shelves) {
|
||
|
|
const over = islands.filter((isle) => {
|
||
|
|
return isle.l < shelf.r - 0.5 && isle.r > shelf.l + 0.5 && Math.abs(isle.bottom - shelf.y) < 1;
|
||
|
|
});
|
||
|
|
const top = ({});
|
||
|
|
plan.tops[shelf.key] = top;
|
||
|
|
if (over.length === 0)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
for (let k = 0; k < over.length; k++) {
|
||
|
|
const isle = over[k];
|
||
|
|
const first = isle.keys[0];
|
||
|
|
const last = isle.keys[isle.keys.length - 1];
|
||
|
|
const tall = isle.bottom - isle.top;
|
||
|
|
const dl = isle.l - shelf.l;
|
||
|
|
if (k > 0) {
|
||
|
|
const f = Math.floor(Math.min(most, (isle.l - over[k - 1].r) / 2, tall));
|
||
|
|
fillet(isle.l - f + bite, shelf.y - f + bite, f, false, true);
|
||
|
|
cap(first, "bl", 0);
|
||
|
|
} else if (dl > 0.5) {
|
||
|
|
const f = Math.floor(Math.min(most, dl / 2, tall));
|
||
|
|
fillet(isle.l - f + bite, shelf.y - f + bite, f, false, true);
|
||
|
|
cap(first, "bl", 0);
|
||
|
|
top.tl = dl - f;
|
||
|
|
} else if (dl < -0.5) {
|
||
|
|
const f = Math.floor(Math.min(most, -dl / 2, shelf.depth / 2));
|
||
|
|
fillet(shelf.l - f + bite, shelf.y - bite, f, false, false);
|
||
|
|
cap(first, "bl", -dl - f);
|
||
|
|
top.tl = 0;
|
||
|
|
} else {
|
||
|
|
cap(first, "bl", 0);
|
||
|
|
top.tl = 0;
|
||
|
|
}
|
||
|
|
const dr = shelf.r - isle.r;
|
||
|
|
if (k < over.length - 1) {
|
||
|
|
const f = Math.floor(Math.min(most, (over[k + 1].l - isle.r) / 2, tall));
|
||
|
|
fillet(isle.r - bite, shelf.y - f + bite, f, true, true);
|
||
|
|
cap(last, "br", 0);
|
||
|
|
} else if (dr > 0.5) {
|
||
|
|
const f = Math.floor(Math.min(most, dr / 2, tall));
|
||
|
|
fillet(isle.r - bite, shelf.y - f + bite, f, true, true);
|
||
|
|
cap(last, "br", 0);
|
||
|
|
top.tr = dr - f;
|
||
|
|
} else if (dr < -0.5) {
|
||
|
|
const f = Math.floor(Math.min(most, -dr / 2, shelf.depth / 2));
|
||
|
|
fillet(shelf.r - bite, shelf.y - bite, f, true, false);
|
||
|
|
cap(last, "br", -dr - f);
|
||
|
|
top.tr = 0;
|
||
|
|
} else {
|
||
|
|
cap(last, "br", 0);
|
||
|
|
top.tr = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return plan;
|
||
|
|
}
|
||
|
|
|
||
|
|
property real wsCollapse: (workspacesMod.expanded && !Prefs.barPopupMode) ? 0 : 1
|
||
|
|
|
||
|
|
// the modules are addressed by their id in Prefs.barModules; the
|
||
|
|
// groups in Prefs.barLayout decide which slot each one lands in
|
||
|
|
readonly property var pillFor: ({
|
||
|
|
"workspaces": workspacesMod,
|
||
|
|
"media": mprisMod,
|
||
|
|
"tray": sysTrayMod,
|
||
|
|
"clock": clockMod,
|
||
|
|
"notifications": notifMod,
|
||
|
|
"system": systemMod,
|
||
|
|
"privacy": privacyMod,
|
||
|
|
"power": powerMod,
|
||
|
|
"window": windowMod,
|
||
|
|
"start": startMod
|
||
|
|
})
|
||
|
|
// what BarPill looks itself up in, for a right click to its card
|
||
|
|
readonly property var moduleById: bar.pillFor
|
||
|
|
readonly property var modules: [workspacesMod, mprisMod, sysTrayMod, clockMod, notifMod, systemMod, privacyMod, powerMod, windowMod, startMod]
|
||
|
|
|
||
|
|
// which modules switched on have left the bar for now, for the Bar
|
||
|
|
// page's arrangement
|
||
|
|
Binding {
|
||
|
|
target: Prefs
|
||
|
|
property: "barModulesAway"
|
||
|
|
when: bar.primary
|
||
|
|
value: Prefs.barModules.filter((m) => {
|
||
|
|
const mod = bar.pillFor[m.id];
|
||
|
|
return Prefs[m.key] === true && mod && !mod.shown;
|
||
|
|
}).map((m) => {
|
||
|
|
return m.id;
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// a module on its way out of the bar keeps the slot it had until its
|
||
|
|
// pill has finished emptying, so its neighbours close the gap at the
|
||
|
|
// rate it shrinks rather than dropping into it
|
||
|
|
function zoneKeys(zone) {
|
||
|
|
const live = bar.dragGroups ? bar.dragGroups[zone === "centre" ? "center" : zone].filter((id) => {
|
||
|
|
return Prefs.barShown(id);
|
||
|
|
}) : Prefs.barKeysOf(zone);
|
||
|
|
const r = Prefs.barRetiring;
|
||
|
|
if (!r || r.zone !== zone || Prefs.barHas(r.key))
|
||
|
|
return live;
|
||
|
|
|
||
|
|
const out = live.slice();
|
||
|
|
out.splice(Math.min(r.at, out.length), 0, r.key);
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
readonly property var retiring: Prefs.barRetiring
|
||
|
|
|
||
|
|
onRetiringChanged: {
|
||
|
|
if (bar.retiring)
|
||
|
|
retireTimer.restart();
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
Timer {
|
||
|
|
id: retireTimer
|
||
|
|
|
||
|
|
interval: Theme.barMs(560)
|
||
|
|
onTriggered: Prefs.barClearRetiring()
|
||
|
|
}
|
||
|
|
|
||
|
|
// key -> which zone it sits in and how far along
|
||
|
|
readonly property var placeMap: {
|
||
|
|
const out = ({});
|
||
|
|
for (var z = 0; z < Prefs.barZones.length; z++) {
|
||
|
|
const zone = Prefs.barZones[z];
|
||
|
|
const keys = bar.zoneKeys(zone);
|
||
|
|
for (var i = 0; i < keys.length; i++) out[keys[i]] = ({ "zone": zone, "at": i })
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
// workspaces empties its slot as it flies to the screen centre, so the
|
||
|
|
// rest of its zone closes up behind it
|
||
|
|
function realWidthOf(key) {
|
||
|
|
const it = bar.pillFor[key];
|
||
|
|
if (!it)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
return it === workspacesMod ? it.width * bar.wsCollapse : it.width;
|
||
|
|
}
|
||
|
|
|
||
|
|
// in edit mode a module with nothing to show keeps a stand-in's room
|
||
|
|
function widthOf(key) {
|
||
|
|
return Math.max(bar.realWidthOf(key), barEdit.ghostWidthOf(key));
|
||
|
|
}
|
||
|
|
|
||
|
|
function widthsOf(zone) {
|
||
|
|
return bar.zoneKeys(zone).map(bar.widthOf);
|
||
|
|
}
|
||
|
|
|
||
|
|
function placesOf(zone) {
|
||
|
|
return zone === "left" ? bar.leftPlaces : (zone === "centre" ? bar.centrePlaces : bar.rightPlaces);
|
||
|
|
}
|
||
|
|
|
||
|
|
function alignFor(zone) {
|
||
|
|
return zone === "centre" ? "center" : (zone === "right" ? "right" : "left");
|
||
|
|
}
|
||
|
|
|
||
|
|
function placeFor(key) {
|
||
|
|
const at = bar.placeMap[key];
|
||
|
|
if (!at)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
const places = bar.placesOf(at.zone);
|
||
|
|
return at.at < places.length ? places[at.at] : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
function alignOf(key) {
|
||
|
|
const at = bar.placeMap[key];
|
||
|
|
return bar.alignFor(at ? at.zone : "left");
|
||
|
|
}
|
||
|
|
|
||
|
|
readonly property var leftWidths: bar.widthsOf("left")
|
||
|
|
readonly property var centreWidths: bar.widthsOf("centre")
|
||
|
|
readonly property var rightWidths: bar.widthsOf("right")
|
||
|
|
readonly property real leftGroupWidth: bar.placeGroup(bar.leftWidths, 0, bar.zoneKeys("left"))[bar.leftWidths.length]
|
||
|
|
readonly property real centreGroupWidth: bar.placeGroup(bar.centreWidths, 0, bar.zoneKeys("centre"))[bar.centreWidths.length]
|
||
|
|
readonly property real rightGroupWidth: bar.placeGroup(bar.rightWidths, 0, bar.zoneKeys("right"))[bar.rightWidths.length]
|
||
|
|
readonly property int zoneGap: Theme.dp(Prefs.barZoneGap)
|
||
|
|
|
||
|
|
// pills ease to their new slots only while the arrangement is changing.
|
||
|
|
// a Behavior left on all the time would sit on top of the width
|
||
|
|
// animations a panel opening or a tray icon arriving already drive, and
|
||
|
|
// one that restarts every frame never arrives
|
||
|
|
readonly property int reorderTick: Prefs.barReorderTick
|
||
|
|
property bool shuffling: false
|
||
|
|
|
||
|
|
onReorderTickChanged: {
|
||
|
|
bar.shuffling = true;
|
||
|
|
shuffleTimer.restart();
|
||
|
|
}
|
||
|
|
|
||
|
|
Timer {
|
||
|
|
id: shuffleTimer
|
||
|
|
|
||
|
|
interval: Theme.barMs(520)
|
||
|
|
onTriggered: bar.shuffling = false
|
||
|
|
}
|
||
|
|
|
||
|
|
readonly property real leftOriginX: bar.sideMargin
|
||
|
|
readonly property real rightOriginX: bar.width - bar.rightGroupWidth - bar.sideMargin
|
||
|
|
readonly property real centreOriginX: Math.min(Math.max((bar.width - bar.centreGroupWidth) / 2, bar.leftOriginX + bar.leftGroupWidth + bar.zoneGap), bar.rightOriginX - bar.centreGroupWidth - bar.zoneGap)
|
||
|
|
readonly property var leftPlaces: bar.placeGroup(bar.leftWidths, bar.leftOriginX, bar.zoneKeys("left"))
|
||
|
|
readonly property var centrePlaces: bar.placeGroup(bar.centreWidths, bar.centreOriginX, bar.zoneKeys("centre"))
|
||
|
|
readonly property var rightPlaces: bar.placeGroup(bar.rightWidths, bar.rightOriginX, bar.zoneKeys("right"))
|
||
|
|
|
||
|
|
Behavior on wsCollapse {
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barMs(380)
|
||
|
|
easing.type: Easing.OutCubic
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
readonly property real sideMargin: Theme.dp(Prefs.barSideMargin)
|
||
|
|
|
||
|
|
// busy: a panel is open somewhere on the bar, so it stays out
|
||
|
|
// regardless of the pointer. held: the pointer is on the reveal
|
||
|
|
// strip or already on a module - either keeps it from hiding
|
||
|
|
readonly property bool barBusy: bar.modules.some((m) => {
|
||
|
|
return m.expanded === true || m.anyOpen === true;
|
||
|
|
})
|
||
|
|
property bool slidingAway: false
|
||
|
|
readonly property bool heldByPointer: Prefs.barAutoHide && (revealArea.containsMouse || (!bar.slidingAway && bar.modules.some((m) => {
|
||
|
|
return m.visible && (m.surfaceHovered === true || m.compactHovered === true);
|
||
|
|
})))
|
||
|
|
readonly property bool barRevealed: !Prefs.barAutoHide || bar.barBusy || bar.heldByPointer || Edit.active
|
||
|
|
// how far the compact content sits above its resting y=0 while
|
||
|
|
// hidden - past the window's own top edge, so it clips away for free
|
||
|
|
property real hiddenOffset: bar.barRevealed ? 0 : -(Theme.dp(Prefs.barHeight) + Prefs.effectiveBarTopMargin + Theme.dp(4))
|
||
|
|
|
||
|
|
Behavior on hiddenOffset {
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.durLong
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
onBarRevealedChanged: {
|
||
|
|
if (bar.barRevealed) {
|
||
|
|
bar.slidingAway = false;
|
||
|
|
slideAwayTimer.stop();
|
||
|
|
} else {
|
||
|
|
bar.slidingAway = true;
|
||
|
|
slideAwayTimer.restart();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Timer {
|
||
|
|
id: slideAwayTimer
|
||
|
|
|
||
|
|
interval: Theme.durLong
|
||
|
|
onTriggered: bar.slidingAway = false
|
||
|
|
}
|
||
|
|
|
||
|
|
Component.onCompleted: laidOutTimer.start()
|
||
|
|
|
||
|
|
Timer {
|
||
|
|
id: laidOutTimer
|
||
|
|
|
||
|
|
interval: 120
|
||
|
|
onTriggered: bar.laidOut = true
|
||
|
|
}
|
||
|
|
|
||
|
|
color: "transparent"
|
||
|
|
implicitHeight: bar.screen ? bar.screen.height - Prefs.effectiveBarTopMargin : Theme.dp(800)
|
||
|
|
exclusiveZone: (Prefs.barEnabled && bar.anyModuleShown && !Prefs.barAutoHide) ? Theme.dp(Prefs.barHeight) + Prefs.shellGap : 0
|
||
|
|
|
||
|
|
anchors {
|
||
|
|
top: true
|
||
|
|
bottom: false
|
||
|
|
left: true
|
||
|
|
right: true
|
||
|
|
}
|
||
|
|
|
||
|
|
margins {
|
||
|
|
top: Prefs.effectiveBarTopMargin
|
||
|
|
}
|
||
|
|
|
||
|
|
// full bar: one strip across the whole top edge, under every module
|
||
|
|
Rectangle {
|
||
|
|
id: fullStrip
|
||
|
|
|
||
|
|
visible: Prefs.barFull && bar.anyModuleShown
|
||
|
|
x: 0
|
||
|
|
y: bar.hiddenOffset
|
||
|
|
z: -2
|
||
|
|
width: bar.width
|
||
|
|
height: Theme.dp(Prefs.barHeight)
|
||
|
|
color: Theme.bg
|
||
|
|
|
||
|
|
Behavior on color {
|
||
|
|
enabled: bar.laidOut
|
||
|
|
|
||
|
|
ColorAnimation {
|
||
|
|
duration: Theme.barMs(260)
|
||
|
|
easing.type: Easing.OutCubic
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// rounded corners hanging off the strip where it meets the screen sides
|
||
|
|
BarFlare {
|
||
|
|
visible: fullStrip.visible && size > 0
|
||
|
|
mirrored: true
|
||
|
|
size: Theme.dp(Prefs.barFullCorner)
|
||
|
|
x: 0
|
||
|
|
y: Theme.dp(Prefs.barHeight) + bar.hiddenOffset
|
||
|
|
z: -2
|
||
|
|
}
|
||
|
|
|
||
|
|
BarFlare {
|
||
|
|
visible: fullStrip.visible && size > 0
|
||
|
|
size: Theme.dp(Prefs.barFullCorner)
|
||
|
|
x: bar.width - width
|
||
|
|
y: Theme.dp(Prefs.barHeight) + bar.hiddenOffset
|
||
|
|
z: -2
|
||
|
|
}
|
||
|
|
|
||
|
|
// full bar: an open panel hangs off the strip, so round the two concave
|
||
|
|
// corners where its sides meet the strip's lower edge. They grow with
|
||
|
|
// the panel's height, so a folding panel takes them with it
|
||
|
|
Repeater {
|
||
|
|
model: (Prefs.barFull && !Prefs.barPopupMode) ? bar.modules.filter((m) => {
|
||
|
|
return m !== workspacesMod;
|
||
|
|
}) : []
|
||
|
|
|
||
|
|
Item {
|
||
|
|
id: panelFlares
|
||
|
|
|
||
|
|
required property var modelData
|
||
|
|
|
||
|
|
// surfaceOpen, not the height alone: a pill that is only
|
||
|
|
// resizing its compact face is see-through on the full bar
|
||
|
|
readonly property real reach: (panelFlares.modelData.visible && panelFlares.modelData.surfaceOpen === true) ? panelFlares.modelData.height - Theme.dp(Prefs.barHeight) : 0
|
||
|
|
|
||
|
|
// never past the screen edge, and never into the screen corner
|
||
|
|
// that already rounds that side
|
||
|
|
function sizeFor(toTheLeft) {
|
||
|
|
var m = panelFlares.modelData;
|
||
|
|
var corner = Theme.dp(Prefs.barFullCorner);
|
||
|
|
var toEdge = toTheLeft ? m.x : bar.width - m.x - m.width;
|
||
|
|
var room = toEdge - (toEdge < corner * 2 ? corner : 0);
|
||
|
|
return Math.max(0, Math.floor(Math.min(corner, panelFlares.reach, room)));
|
||
|
|
}
|
||
|
|
|
||
|
|
anchors.fill: parent
|
||
|
|
z: -1
|
||
|
|
|
||
|
|
BarFlare {
|
||
|
|
size: panelFlares.sizeFor(true)
|
||
|
|
x: panelFlares.modelData.x - width + 0.5
|
||
|
|
y: Theme.dp(Prefs.barHeight)
|
||
|
|
}
|
||
|
|
|
||
|
|
BarFlare {
|
||
|
|
mirrored: true
|
||
|
|
size: panelFlares.sizeFor(false)
|
||
|
|
x: panelFlares.modelData.x + panelFlares.modelData.width - 0.5
|
||
|
|
y: Theme.dp(Prefs.barHeight)
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
Mpris {
|
||
|
|
id: mprisMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("media")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
x: bar.xOf("media")
|
||
|
|
editLifted: bar.dragKey === "media"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("media")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "media"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
SysTray {
|
||
|
|
id: sysTrayMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("tray")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
x: bar.xOf("tray")
|
||
|
|
editLifted: bar.dragKey === "tray"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("tray")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "tray"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
Clock {
|
||
|
|
id: clockMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("clock")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("clock")
|
||
|
|
x: bar.xOf("clock")
|
||
|
|
editLifted: bar.dragKey === "clock"
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "clock"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
Notifications {
|
||
|
|
id: notifMod
|
||
|
|
|
||
|
|
showsPopups: bar.primary
|
||
|
|
popupAlign: bar.alignOf("notifications")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
x: bar.xOf("notifications")
|
||
|
|
editLifted: bar.dragKey === "notifications"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("notifications")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "notifications"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
Privacy {
|
||
|
|
id: privacyMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("privacy")
|
||
|
|
toast: bar.primary ? toastMod : null
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
x: bar.xOf("privacy")
|
||
|
|
editLifted: bar.dragKey === "privacy"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("privacy")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "privacy"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
SessionMenu {
|
||
|
|
id: powerMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("power")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
x: bar.xOf("power")
|
||
|
|
editLifted: bar.dragKey === "power"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("power")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "power"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
StartButton {
|
||
|
|
id: startMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("start")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
dockMod: dock
|
||
|
|
x: bar.xOf("start")
|
||
|
|
editLifted: bar.dragKey === "start"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("start")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "start"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
ActiveWindow {
|
||
|
|
id: windowMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("window")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
x: bar.xOf("window")
|
||
|
|
editLifted: bar.dragKey === "window"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("window")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "window"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
System {
|
||
|
|
id: systemMod
|
||
|
|
|
||
|
|
popupAlign: bar.alignOf("system")
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
mprisMod: mprisMod
|
||
|
|
x: bar.xOf("system")
|
||
|
|
editLifted: bar.dragKey === "system"
|
||
|
|
anchors.top: parent.top
|
||
|
|
anchors.topMargin: bar.hiddenOffset + bar.liftOf("system")
|
||
|
|
|
||
|
|
Behavior on x {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "system"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
Repeater {
|
||
|
|
model: Prefs.barNotch ? bar.modules : []
|
||
|
|
|
||
|
|
Item {
|
||
|
|
id: flares
|
||
|
|
|
||
|
|
required property var modelData
|
||
|
|
|
||
|
|
readonly property bool present: flares.modelData && flares.modelData.width > 0.5 && flares.modelData.visible && !(bar.dragLift > 0.5 && bar.pillFor[bar.dragKey] === flares.modelData)
|
||
|
|
readonly property bool modHovered: flares.modelData ? (flares.modelData.compactHovered === true && flares.modelData !== workspacesMod) : false
|
||
|
|
|
||
|
|
function flareFor(toTheLeft) {
|
||
|
|
if (!flares.present)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
var mods = bar.modules;
|
||
|
|
var edge = toTheLeft ? flares.modelData.x : flares.modelData.x + flares.modelData.width;
|
||
|
|
var toEdge = toTheLeft ? edge : bar.width - edge;
|
||
|
|
var toNeighbour = 100000;
|
||
|
|
for (var i = 0; i < mods.length; i++) {
|
||
|
|
var o = mods[i];
|
||
|
|
if (!o || o === flares.modelData || o.width <= 0.5 || !o.visible)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
var d = toTheLeft ? edge - (o.x + o.width) : o.x - edge;
|
||
|
|
if (d >= 0)
|
||
|
|
toNeighbour = Math.min(toNeighbour, d);
|
||
|
|
|
||
|
|
}
|
||
|
|
return Math.max(0, Math.min(Theme.dp(Prefs.barNotchFlare), Math.floor(toNeighbour / 2), Math.floor(toEdge)));
|
||
|
|
}
|
||
|
|
|
||
|
|
anchors.fill: parent
|
||
|
|
z: -1
|
||
|
|
visible: Prefs.barNotch && flares.present
|
||
|
|
|
||
|
|
readonly property real bite: 0.5
|
||
|
|
|
||
|
|
BarFlare {
|
||
|
|
hovered: flares.modHovered
|
||
|
|
size: flares.flareFor(true)
|
||
|
|
x: flares.modelData ? flares.modelData.x - width + flares.bite : 0
|
||
|
|
y: bar.hiddenOffset
|
||
|
|
}
|
||
|
|
|
||
|
|
BarFlare {
|
||
|
|
hovered: flares.modHovered
|
||
|
|
mirrored: true
|
||
|
|
size: flares.flareFor(false)
|
||
|
|
x: flares.modelData ? flares.modelData.x + flares.modelData.width - flares.bite : 0
|
||
|
|
y: bar.hiddenOffset
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// fillets where a hanging panel meets the islands above it
|
||
|
|
Repeater {
|
||
|
|
model: 16
|
||
|
|
|
||
|
|
BarFlare {
|
||
|
|
required property int index
|
||
|
|
readonly property var spec: bar.hangPlan.fillets.length > index ? bar.hangPlan.fillets[index] : null
|
||
|
|
|
||
|
|
z: 0
|
||
|
|
size: spec ? spec.size : 0
|
||
|
|
mirrored: spec ? spec.mirrored : false
|
||
|
|
flipped: spec ? spec.flipped : false
|
||
|
|
x: spec ? spec.x : 0
|
||
|
|
y: spec ? spec.y : 0
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
Workspaces {
|
||
|
|
id: workspacesMod
|
||
|
|
|
||
|
|
hostWindow: bar
|
||
|
|
dockMod: dock
|
||
|
|
restX: bar.xOf("workspaces")
|
||
|
|
restY: bar.hiddenOffset + bar.liftOf("workspaces")
|
||
|
|
z: bar.dragKey === "workspaces" ? 120 : (workspacesMod.popupOpen ? 100 : 1)
|
||
|
|
|
||
|
|
Behavior on restX {
|
||
|
|
enabled: bar.laidOut && bar.shuffling && bar.dragKey !== "workspaces"
|
||
|
|
|
||
|
|
NumberAnimation {
|
||
|
|
duration: Theme.barDurEnter
|
||
|
|
easing.type: Easing.Bezier
|
||
|
|
easing.bezierCurve: Theme.easeEmphasizedDecel
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
mask: Region {
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: workspacesMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: mprisMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: sysTrayMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: clockMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: notifMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: systemMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: privacyMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: powerMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: windowMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
mod: startMod
|
||
|
|
}
|
||
|
|
|
||
|
|
Region {
|
||
|
|
item: Prefs.barAutoHide ? revealArea : null
|
||
|
|
}
|
||
|
|
|
||
|
|
Region {
|
||
|
|
width: bar.dragHeld || Edit.active ? bar.width : 0
|
||
|
|
height: bar.dragHeld ? bar.height : (Edit.active ? Theme.dp(Prefs.barHeight) + Theme.dp(4) : 0)
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
BarEdit {
|
||
|
|
id: barEdit
|
||
|
|
|
||
|
|
host: bar
|
||
|
|
}
|
||
|
|
|
||
|
|
// touching this strip reveals the bar
|
||
|
|
MouseArea {
|
||
|
|
id: revealArea
|
||
|
|
|
||
|
|
x: 0
|
||
|
|
y: 0
|
||
|
|
width: bar.width
|
||
|
|
height: Theme.dp(4)
|
||
|
|
hoverEnabled: true
|
||
|
|
acceptedButtons: Qt.NoButton
|
||
|
|
enabled: Prefs.barAutoHide
|
||
|
|
visible: Prefs.barAutoHide
|
||
|
|
}
|
||
|
|
|
||
|
|
// the overview and the dock menu shut each other
|
||
|
|
Connections {
|
||
|
|
function onExpandedChanged() {
|
||
|
|
if (workspacesMod.expanded)
|
||
|
|
dock.menuOpen = false;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
target: workspacesMod
|
||
|
|
}
|
||
|
|
|
||
|
|
Connections {
|
||
|
|
function onMenuOpenChanged() {
|
||
|
|
if (dock.menuOpen)
|
||
|
|
workspacesMod.expanded = false;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
target: dock
|
||
|
|
}
|
||
|
|
|
||
|
|
BackgroundEffect.blurRegion: (Theme.blurAmount > 0 && bar.laidOut) ? barBlurRegion : null
|
||
|
|
|
||
|
|
// clipped to the surface: hyprland frosts the whole layer for a region
|
||
|
|
// wholly outside it, which is where a hidden bar's pills are
|
||
|
|
Region {
|
||
|
|
id: barBlurRegion
|
||
|
|
|
||
|
|
intersection: Intersection.Intersect
|
||
|
|
|
||
|
|
Region {
|
||
|
|
x: 0
|
||
|
|
y: fullStrip.visible ? bar.hiddenOffset : 0
|
||
|
|
width: fullStrip.visible ? Math.round(bar.width) : 0
|
||
|
|
height: fullStrip.visible ? Theme.dp(Prefs.barHeight) : 0
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: workspacesMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: mprisMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: sysTrayMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: clockMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: notifMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: systemMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: privacyMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: powerMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: windowMod
|
||
|
|
}
|
||
|
|
|
||
|
|
ModuleRegion {
|
||
|
|
blur: true
|
||
|
|
mod: startMod
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|