Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions modules/features/core/boot.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ in
enable = true;
efiSupport = true;
device = "nodev";
useOSProber = true;
dedsec-theme = {
enable = true;
style = "legion";
Expand Down
1 change: 0 additions & 1 deletion modules/features/desktop/hyprland.nix
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ let
hl.on("hyprland.start", function()
hl.exec_cmd("dbus-update-activation-environment --systemd DISPLAY HYPRLAND_INSTANCE_SIGNATURE WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE && systemctl --user stop hyprland-session.target && systemctl --user start hyprland-session.target")
hl.exec_cmd("systemctl --user start hyprpolkitagent")
hl.exec_cmd("ctos-shell")
end)

hl.config({
Expand Down
3 changes: 0 additions & 3 deletions modules/features/desktop/niri.nix
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ let
"systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP DISPLAY GTK_USE_PORTAL NIRI_SOCKET && systemctl --user start nixos-fake-graphical-session.target"
];
}
{
command = [ "ctos-shell" ];
}
{
command = [ "hypridle" ];
}
Expand Down
12 changes: 12 additions & 0 deletions shell/desktop/core/Settings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Singleton {
readonly property bool defaultWidgetTargetProfilerVisible: true
property bool featuresCommandDeck: true
property bool featuresNotifications: true
property int notificationCooldownSeconds: 30
readonly property int defaultNotificationCooldownSeconds: 30
property bool featuresSystemRail: true

// Indicator if configuration was successfully loaded from disk
Expand Down Expand Up @@ -132,6 +134,14 @@ Singleton {
featuresNotifications = defaultFeaturesNotifications;
}

if (typeof data.notificationCooldownSeconds === "number" && Number.isInteger(data.notificationCooldownSeconds) && data.notificationCooldownSeconds >= 0) {
notificationCooldownSeconds = data.notificationCooldownSeconds;
} else if (data.features && typeof data.features.notificationCooldownSeconds === "number" && Number.isInteger(data.features.notificationCooldownSeconds) && data.features.notificationCooldownSeconds >= 0) {
notificationCooldownSeconds = data.features.notificationCooldownSeconds;
} else {
notificationCooldownSeconds = defaultNotificationCooldownSeconds;
}

// barHeight: supports flat key or nested bar.height
if (typeof data.barHeight === "number" && Number.isInteger(data.barHeight) && data.barHeight > 0) {
barHeight = data.barHeight;
Expand Down Expand Up @@ -311,6 +321,7 @@ Singleton {
data.featuresCommandDeck = root.featuresCommandDeck;
data.featuresSystemRail = root.featuresSystemRail;
data.featuresNotifications = root.featuresNotifications;
data.notificationCooldownSeconds = root.notificationCooldownSeconds;
data.barHeight = root.barHeight;
data.theme = root.theme;
data.wallpaper = root.wallpaper;
Expand Down Expand Up @@ -511,6 +522,7 @@ Singleton {
featuresCommandDeck = defaultFeaturesCommandDeck;
featuresSystemRail = defaultFeaturesSystemRail;
featuresNotifications = defaultFeaturesNotifications;
notificationCooldownSeconds = defaultNotificationCooldownSeconds;
barHeight = defaultBarHeight;
theme = defaultTheme;
wallpaper = defaultWallpaper;
Expand Down
24 changes: 23 additions & 1 deletion shell/desktop/services/NotificationService.qml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ Singleton {
// Map of notifId -> raw Notification object
property var _notificationObjects: ({})

// Map of "appName|summary" -> timestamp
property var _recentNotifications: ({})

// Component for instantiating per-toast auto-expiry timers
Component {
id: toastTimerComponent
Expand Down Expand Up @@ -178,6 +181,25 @@ Singleton {
} catch (e) {}
}

const dedupKey = appName + "|" + summary;
const now = Date.now();

// Clean up expired entries to prevent memory leak
const cutoff = now - Settings.notificationCooldownSeconds * 1000;
for (let key in root._recentNotifications) {
if (root._recentNotifications[key] < cutoff) {
delete root._recentNotifications[key];
}
}

let isDuplicate = false;
if (root._recentNotifications[dedupKey] !== undefined) {
if (now - root._recentNotifications[dedupKey] < Settings.notificationCooldownSeconds * 1000) {
isDuplicate = true;
}
}
root._recentNotifications[dedupKey] = now;

const record = {
notifId: notifId,
id: notifId,
Expand All @@ -199,7 +221,7 @@ Singleton {
}
historyModel.insert(0, record);

if (!root.doNotDisturb) {
if (!root.doNotDisturb && !isDuplicate) {
for (let t = activeToastsModel.count - 1; t >= 0; --t) {
const existingToast = activeToastsModel.get(t);
if (existingToast && (existingToast.notifId === notifId || existingToast.id === notifId)) {
Expand Down
37 changes: 24 additions & 13 deletions shell/desktop/surfaces/components/CalendarPopup.qml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,30 @@ Rectangle {
// Calendar State & Calculations
// =========================================================================

property int viewYear: (new Date()).getFullYear()
property int viewMonth: (new Date()).getMonth()
SystemClock {
id: systemClock

precision: SystemClock.Minute
}

property int todayYear: systemClock.date.getFullYear()
property int todayMonth: systemClock.date.getMonth()
property int todayDate: systemClock.date.getDate()

property int viewYear: todayYear
property int viewMonth: todayMonth

readonly property var monthNames: ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"]

readonly property var dayHeaders: ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]

readonly property var gridCells: generateCalendarCells(root.viewYear, root.viewMonth)
readonly property var gridCells: generateCalendarCells(root.viewYear, root.viewMonth, root.todayYear, root.todayMonth, root.todayDate)

onVisibleChanged: {
if (visible) {
resetToToday();
}
}

function previousMonth(): void {
if (viewMonth === 0) {
Expand All @@ -74,17 +90,12 @@ Rectangle {
}

function resetToToday(): void {
const now = new Date();
viewYear = now.getFullYear();
viewMonth = now.getMonth();
viewYear = Qt.binding(function() { return todayYear; });
viewMonth = Qt.binding(function() { return todayMonth; });
}

function generateCalendarCells(year: int, month: int): var {
function generateCalendarCells(year: int, month: int, tYear: int, tMonth: int, tDate: int): var {
const cells = [];
const today = new Date();
const todayYear = today.getFullYear();
const todayMonth = today.getMonth();
const todayDate = today.getDate();

const firstDay = new Date(year, month, 1);
const firstDayIndex = (firstDay.getDay() + 6) % 7;
Expand All @@ -111,7 +122,7 @@ Rectangle {
cellYear = month === 11 ? year + 1 : year;
}

const isToday = (cellYear === todayYear && cellMonth === todayMonth && dayNum === todayDate && isCurrentMonth);
const isToday = (cellYear === tYear && cellMonth === tMonth && dayNum === tDate && isCurrentMonth);

cells.push({
day: dayNum,
Expand Down Expand Up @@ -361,7 +372,7 @@ Rectangle {
color: Theme.textMuted
font.family: Theme.fontFamilyMonospace
font.pixelSize: Theme.fontSizeCaption
text: "// " + Qt.formatDateTime(new Date(), "yyyy-MM-dd")
text: "// " + Qt.formatDateTime(systemClock.date, "yyyy-MM-dd")
}

Rectangle {
Expand Down
20 changes: 20 additions & 0 deletions shell/greeter/common/components/Accents.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import QtQuick

import qs.greeter.config

import Qt5Compat.GraphicalEffects

Item {
id: root

Expand All @@ -12,6 +14,8 @@ Item {
property bool animate: true
property int individualSize: 4

property color tintColor: "transparent"

property int startingHorizontalOffset: 0
property int startingVerticalOffset: 0

Expand Down Expand Up @@ -44,6 +48,10 @@ Item {
top: root.top
topMargin: root._verticalOffset
}
layer.enabled: !Qt.colorEqual(root.tintColor, "transparent")
layer.effect: ColorOverlay {
color: root.tintColor
}
}

Image {
Expand All @@ -58,6 +66,10 @@ Item {
bottomMargin: root._verticalOffset
}
rotation: 270
layer.enabled: !Qt.colorEqual(root.tintColor, "transparent")
layer.effect: ColorOverlay {
color: root.tintColor
}
}

Image {
Expand All @@ -72,6 +84,10 @@ Item {
topMargin: root._verticalOffset
}
rotation: 90
layer.enabled: !Qt.colorEqual(root.tintColor, "transparent")
layer.effect: ColorOverlay {
color: root.tintColor
}
}

Image {
Expand All @@ -86,6 +102,10 @@ Item {
bottomMargin: root._verticalOffset
}
rotation: 180
layer.enabled: !Qt.colorEqual(root.tintColor, "transparent")
layer.effect: ColorOverlay {
color: root.tintColor
}
}

ParallelAnimation {
Expand Down
Loading
Loading