Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
ximper-shell-notification-center
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ximper Linux
ximper-shell-notification-center
Commits
63e9d221
Commit
63e9d221
authored
Jan 02, 2026
by
Erik Reider
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplified finding notification widgets when replacing and removing
parent
42d06db3
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
101 additions
and
65 deletions
+101
-65
notifications.vala
src/controlCenter/widgets/notifications/notifications.vala
+9
-6
notiDaemon.vala
src/notiDaemon/notiDaemon.vala
+1
-1
expandableGroup.vala
src/notificationGroup/expandableGroup.vala
+33
-2
notificationGroup.vala
src/notificationGroup/notificationGroup.vala
+26
-35
notificationWindow.vala
src/notificationWindow/notificationWindow.vala
+32
-21
No files found.
src/controlCenter/widgets/notifications/notifications.vala
View file @
63e9d221
...
@@ -114,7 +114,7 @@ namespace SwayNotificationCenter.Widgets {
...
@@ -114,7 +114,7 @@ namespace SwayNotificationCenter.Widgets {
private
void
prepare_group_removal
(
NotificationGroup
group
)
{
private
void
prepare_group_removal
(
NotificationGroup
group
)
{
if
(
group
.
name_id
.
length
>
0
)
{
if
(
group
.
name_id
.
length
>
0
)
{
noti_groups_name
.
unset
(
group
.
name_id
,
null
);
noti_groups_name
.
unset
(
group
.
name_id
);
}
}
if
(
expanded_group
==
group
)
{
if
(
expanded_group
==
group
)
{
expanded_group
=
null
;
expanded_group
=
null
;
...
@@ -175,8 +175,8 @@ namespace SwayNotificationCenter.Widgets {
...
@@ -175,8 +175,8 @@ namespace SwayNotificationCenter.Widgets {
}
}
private
void
remove_group_internal
(
NotificationGroup
group
)
{
private
void
remove_group_internal
(
NotificationGroup
group
)
{
foreach
(
uint32
id
in
group
.
notification_ids
)
{
foreach
(
uint32
id
in
group
.
notification_ids
.
keys
)
{
if
(
noti_groups_id
.
unset
(
id
,
null
))
{
if
(
noti_groups_id
.
unset
(
id
))
{
n_notifications
--;
n_notifications
--;
}
}
}
}
...
@@ -197,6 +197,7 @@ namespace SwayNotificationCenter.Widgets {
...
@@ -197,6 +197,7 @@ namespace SwayNotificationCenter.Widgets {
return
;
return
;
}
}
if
(
group
.
state
==
NotificationGroupState
.
MANY
)
{
if
(
group
.
state
==
NotificationGroupState
.
MANY
)
{
noti_groups_id
.
unset
(
id
);
n_notifications
--;
n_notifications
--;
group
.
remove_notification
.
begin
(
id
,
(
obj
,
result
)
=>
{
group
.
remove_notification
.
begin
(
id
,
(
obj
,
result
)
=>
{
// Continue the removal logic even if the async result failed
// Continue the removal logic even if the async result failed
...
@@ -215,8 +216,10 @@ namespace SwayNotificationCenter.Widgets {
...
@@ -215,8 +216,10 @@ namespace SwayNotificationCenter.Widgets {
public
void
replace_notification
(
uint32
id
,
NotifyParams
new_params
)
{
public
void
replace_notification
(
uint32
id
,
NotifyParams
new_params
)
{
unowned
NotificationGroup
?
group
=
noti_groups_id
.
get
(
id
);
unowned
NotificationGroup
?
group
=
noti_groups_id
.
get
(
id
);
if
(
group
!=
null
)
{
if
(
group
!=
null
)
{
noti_groups_id
.
unset
(
id
,
null
);
noti_groups_id
.
unset
(
id
);
if
(
group
.
replace_notification
(
id
,
new_params
))
{
if
(
group
.
replace_notification
(
id
,
new_params
))
{
// Replace the ID, could be changed depending on the
// replacement method used
noti_groups_id
.
set
(
new_params
.
applied_id
,
group
);
noti_groups_id
.
set
(
new_params
.
applied_id
,
group
);
// Position the notification in the beginning of the list
// Position the notification in the beginning of the list
list_box
.
invalidate_sort
();
list_box
.
invalidate_sort
();
...
@@ -268,10 +271,10 @@ namespace SwayNotificationCenter.Widgets {
...
@@ -268,10 +271,10 @@ namespace SwayNotificationCenter.Widgets {
group
.
add_css_class
(
"not-expanded"
);
group
.
add_css_class
(
"not-expanded"
);
}
}
noti_groups_id
.
set
(
param
.
applied_id
,
group
);
group
.
add_notification
(
noti
);
group
.
add_notification
(
noti
);
noti_groups_id
.
set
(
param
.
applied_id
,
group
);
n_notifications
++;
n_notifications
++;
list_box
.
invalidate_sort
();
list_box
.
invalidate_sort
();
scroll_to_start
();
scroll_to_start
();
...
...
src/notiDaemon/notiDaemon.vala
View file @
63e9d221
...
@@ -55,7 +55,7 @@ namespace SwayNotificationCenter {
...
@@ -55,7 +55,7 @@ namespace SwayNotificationCenter {
}
}
internal
void
request_dismiss_notification_group
(
string
group_name_id
,
internal
void
request_dismiss_notification_group
(
string
group_name_id
,
Gee
.
Hash
Set
<
uint32
>
ids
,
Gee
.
Set
<
uint32
>
ids
,
ClosedReasons
reason
)
{
ClosedReasons
reason
)
{
debug
(
"Dismissing notification group with ID:%s, reason:%s"
,
debug
(
"Dismissing notification group with ID:%s, reason:%s"
,
group_name_id
,
reason
.
to_string
());
group_name_id
,
reason
.
to_string
());
...
...
src/notificationGroup/expandableGroup.vala
View file @
63e9d221
...
@@ -15,9 +15,10 @@ namespace SwayNotificationCenter {
...
@@ -15,9 +15,10 @@ namespace SwayNotificationCenter {
private
Adw
.
TimedAnimation
animation
;
private
Adw
.
TimedAnimation
animation
;
public
uint
n_children
{
get
;
private
set
;
}
public
uint
n_children
{
get
;
private
set
;
}
public
List
<
Gtk
.
Widget
>
widgets
=
new
List
<
Gtk
.
Widget
>
();
public
List
<
unowned
Gtk
.
Widget
>
visible_widgets
=
new
List
<
unowned
Gtk
.
Widget
>
();
public
List
<
unowned
Gtk
.
Widget
>
visible_widgets
=
new
List
<
unowned
Gtk
.
Widget
>
();
List
<
Gtk
.
Widget
>
widgets
=
new
List
<
Gtk
.
Widget
>
();
public
delegate
void
on_expand_change
(
bool
state
);
public
delegate
void
on_expand_change
(
bool
state
);
private
unowned
Gtk
.
Viewport
viewport
;
private
unowned
Gtk
.
Viewport
viewport
;
...
@@ -94,12 +95,42 @@ namespace SwayNotificationCenter {
...
@@ -94,12 +95,42 @@ namespace SwayNotificationCenter {
bool
widget_visible
=
widget
.
get_visible
();
bool
widget_visible
=
widget
.
get_visible
();
widget
.
unparent
();
widget
.
unparent
();
widgets
.
remove
(
widget
);
widgets
.
remove
(
widget
);
if
(
get_visible
()
&&
widget_visible
)
{
if
(
widget_visible
)
{
queue_resize
();
queue_resize
();
}
}
n_children
--;
n_children
--;
}
}
public
void
remove_all
()
{
while
(!
widgets
.
is_empty
())
{
unowned
List
<
Gtk
.
Widget
>
link
=
widgets
.
nth
(
0
);
if
(
link
.
data
!=
null
&&
link
.
data
is
Gtk
.
Widget
)
{
remove
(
link
.
data
);
}
else
{
widgets
.
delete_link
(
link
);
}
}
warn_if_fail
(
widgets
.
is_empty
());
n_children
=
0
;
}
public
delegate
bool
WidgetFilterDelegate
(
Gtk
.
Widget
widget
);
public
unowned
Gtk
.
Widget
?
get_first_widget
(
WidgetFilterDelegate
?
filter
=
null
)
{
for
(
unowned
List
<
Gtk
.
Widget
>
?
link
=
widgets
.
first
();
link
!=
null
;
link
=
link
.
next
)
{
if
(
link
.
data
!=
null
&&
(
filter
==
null
||
filter
(
link
.
data
)))
{
return
link
.
data
;
}
}
return
null
;
}
public
inline
bool
is_empty
()
{
return
widgets
.
is_empty
();
}
private
delegate
void
compute_height_iter_cb
(
Gtk
.
Widget
child
,
private
delegate
void
compute_height_iter_cb
(
Gtk
.
Widget
child
,
WidgetAlloc
widget_alloc
,
WidgetAlloc
widget_alloc
,
int
index
,
int
index
,
...
...
src/notificationGroup/notificationGroup.vala
View file @
63e9d221
...
@@ -8,10 +8,10 @@ namespace SwayNotificationCenter {
...
@@ -8,10 +8,10 @@ namespace SwayNotificationCenter {
public
class
NotificationGroup
:
Gtk
.
ListBoxRow
{
public
class
NotificationGroup
:
Gtk
.
ListBoxRow
{
public
string
name_id
;
public
string
name_id
;
public
Gee
.
Hash
Set
<
uint32
>
notification_ids
{
public
Gee
.
Hash
Map
<
uint32
,
unowned
Notification
>
notification_ids
{
get
;
get
;
private
set
;
private
set
;
default
=
new
Gee
.
Hash
Set
<
uint32
>
();
default
=
new
Gee
.
Hash
Map
<
uint32
,
unowned
Notification
>
();
}
}
public
NotificationGroupState
state
{
public
NotificationGroupState
state
{
...
@@ -283,12 +283,11 @@ namespace SwayNotificationCenter {
...
@@ -283,12 +283,11 @@ namespace SwayNotificationCenter {
return
;
return
;
}
}
unowned
Notification
first
=
(
Notification
)
group
.
widgets
.
first
().
data
;
unowned
Notification
?
latest
=
get_latest_notification
();
unowned
NotifyParams
param
=
first
.
param
;
// Get the app icon
// Get the app icon
Icon
?
icon
=
null
;
Icon
?
icon
=
null
;
if
(
param
.
desktop_app_info
!=
null
if
(
latest
!=
null
&&
latest
.
param
.
desktop_app_info
!=
null
&&
(
icon
=
param
.
desktop_app_info
.
get_icon
())
!=
null
)
{
&&
(
icon
=
latest
.
param
.
desktop_app_info
.
get_icon
())
!=
null
)
{
app_icon
.
set_from_gicon
(
icon
);
app_icon
.
set_from_gicon
(
icon
);
}
else
{
}
else
{
app_icon
.
set_from_icon_name
(
"application-x-executable-symbolic"
);
app_icon
.
set_from_icon_name
(
"application-x-executable-symbolic"
);
...
@@ -296,13 +295,11 @@ namespace SwayNotificationCenter {
...
@@ -296,13 +295,11 @@ namespace SwayNotificationCenter {
}
}
private
unowned
Notification
?
find_notification
(
uint32
id
)
{
private
unowned
Notification
?
find_notification
(
uint32
id
)
{
foreach
(
unowned
Gtk
.
Widget
widget
in
group
.
widgets
)
{
unowned
Notification
?
notification
=
notification_ids
.
get
(
id
);
unowned
Notification
notification
=
(
Notification
)
widget
;
if
(
notification
==
null
||
notification
.
param
.
applied_id
!=
id
)
{
if
(
notification
!=
null
&&
notification
.
param
.
applied_id
==
id
)
{
return
null
;
return
notification
;
}
}
}
return
n
ull
;
return
n
otification
;
}
}
public
void
set_expanded
(
bool
state
)
{
public
void
set_expanded
(
bool
state
)
{
...
@@ -324,8 +321,8 @@ namespace SwayNotificationCenter {
...
@@ -324,8 +321,8 @@ namespace SwayNotificationCenter {
if
(
noti
.
param
.
urgency
==
UrgencyLevels
.
CRITICAL
)
{
if
(
noti
.
param
.
urgency
==
UrgencyLevels
.
CRITICAL
)
{
urgent_notifications
.
add
(
noti
.
param
.
applied_id
);
urgent_notifications
.
add
(
noti
.
param
.
applied_id
);
}
}
notification_ids
.
add
(
noti
.
param
.
applied_id
);
group
.
add
(
noti
);
group
.
add
(
noti
);
notification_ids
.
set
(
noti
.
param
.
applied_id
,
noti
);
update_state
();
update_state
();
set_icon
();
set_icon
();
...
@@ -336,8 +333,8 @@ namespace SwayNotificationCenter {
...
@@ -336,8 +333,8 @@ namespace SwayNotificationCenter {
if
(
notification
==
null
)
{
if
(
notification
==
null
)
{
return
false
;
return
false
;
}
}
notification_ids
.
remove
(
id
);
notification_ids
.
unset
(
id
);
notification_ids
.
add
(
new_params
.
applied_id
);
notification_ids
.
set
(
new_params
.
applied_id
,
notification
);
notification
.
replace_notification
(
new_params
);
notification
.
replace_notification
(
new_params
);
return
true
;
return
true
;
}
}
...
@@ -352,7 +349,7 @@ namespace SwayNotificationCenter {
...
@@ -352,7 +349,7 @@ namespace SwayNotificationCenter {
}
}
urgent_notifications
.
remove
(
notification
.
param
.
applied_id
);
urgent_notifications
.
remove
(
notification
.
param
.
applied_id
);
notification_ids
.
remove
(
notification
.
param
.
applied_id
);
notification_ids
.
unset
(
notification
.
param
.
applied_id
);
notification
.
remove_noti_timeout
();
notification
.
remove_noti_timeout
();
// Only animate individual notifications when there are more than one,
// Only animate individual notifications when there are more than one,
...
@@ -393,7 +390,7 @@ namespace SwayNotificationCenter {
...
@@ -393,7 +390,7 @@ namespace SwayNotificationCenter {
}
}
}
}
if
(
group
.
widgets
.
is_empty
())
{
if
(
group
.
is_empty
())
{
debug
(
"Skiping removal of all notifications as the group is already empty"
);
debug
(
"Skiping removal of all notifications as the group is already empty"
);
return
false
;
return
false
;
}
}
...
@@ -403,16 +400,7 @@ namespace SwayNotificationCenter {
...
@@ -403,16 +400,7 @@ namespace SwayNotificationCenter {
return
false
;
return
false
;
}
}
while
(!
group
.
widgets
.
is_empty
())
{
group
.
remove_all
();
unowned
List
<
Gtk
.
Widget
>
link
=
group
.
widgets
.
nth
(
0
);
unowned
Notification
?
notification
=
(
Notification
)
link
.
data
;
if
(
notification
!=
null
)
{
notification
.
remove_noti_timeout
();
}
group
.
widgets
.
delete_link
(
link
);
}
warn_if_fail
(
group
.
widgets
.
is_empty
());
return
true
;
return
true
;
}
}
...
@@ -421,19 +409,23 @@ namespace SwayNotificationCenter {
...
@@ -421,19 +409,23 @@ namespace SwayNotificationCenter {
return
;
return
;
}
}
dismissed
=
true
;
dismissed
=
true
;
noti_daemon
.
request_dismiss_notification_group
(
name_id
,
notification_ids
,
noti_daemon
.
request_dismiss_notification_group
(
name_id
,
notification_ids
.
keys
,
ClosedReasons
.
DISMISSED
);
ClosedReasons
.
DISMISSED
);
}
}
public
unowned
Notification
?
get_latest_notification
()
{
public
unowned
Notification
?
get_latest_notification
()
{
return
(
Notification
?)
group
.
widgets
.
first
().
data
;
return
(
Notification
?)
group
.
get_first_widget
((
widget
)
=>
{
unowned
Notification
?
notification
=
(
Notification
?)
widget
;
return
notification
!=
null
&&
!
notification
.
dismissed
;
});
}
}
public
int64
get_time
()
{
public
int64
get_time
()
{
if
(
group
.
widgets
.
is_empty
())
{
unowned
Notification
?
notification
=
get_latest_notification
();
if
(
notification_ids
.
is_empty
||
notification
==
null
)
{
return
-
1
;
return
-
1
;
}
}
return
((
Notification
)
group
.
widgets
.
first
().
data
)
.
param
.
time
;
return
notification
.
param
.
time
;
}
}
public
bool
get_is_urgent
()
{
public
bool
get_is_urgent
()
{
...
@@ -446,10 +438,9 @@ namespace SwayNotificationCenter {
...
@@ -446,10 +438,9 @@ namespace SwayNotificationCenter {
public
void
update
()
{
public
void
update
()
{
set_icon
();
set_icon
();
foreach
(
unowned
Gtk
.
Widget
widget
in
group
.
widgets
)
{
foreach
(
unowned
Notification
?
notification
in
notification_ids
.
values
)
{
var
noti
=
(
Notification
)
widget
;
if
(
notification
!=
null
)
{
if
(
noti
!=
null
)
{
notification
.
set_time
();
noti
.
set_time
();
}
}
}
}
}
}
...
...
src/notificationWindow/notificationWindow.vala
View file @
63e9d221
...
@@ -7,6 +7,8 @@ namespace SwayNotificationCenter {
...
@@ -7,6 +7,8 @@ namespace SwayNotificationCenter {
unowned
AnimatedList
list
;
unowned
AnimatedList
list
;
Gee
.
HashSet
<
uint32
>
inline_reply_notifications
=
new
Gee
.
HashSet
<
uint32
>
();
Gee
.
HashSet
<
uint32
>
inline_reply_notifications
=
new
Gee
.
HashSet
<
uint32
>
();
Gee
.
HashMap
<
uint32
,
unowned
Notification
>
notification_ids
=
new
Gee
.
HashMap
<
uint32
,
unowned
Notification
>
();
private
static
string
?
monitor_name
=
null
;
private
static
string
?
monitor_name
=
null
;
...
@@ -214,6 +216,18 @@ namespace SwayNotificationCenter {
...
@@ -214,6 +216,18 @@ namespace SwayNotificationCenter {
surface
.
set_input_region
(
region
);
surface
.
set_input_region
(
region
);
}
}
private
inline
unowned
Notification
?
find_notification
(
uint32
id
)
{
unowned
Notification
?
notification
=
notification_ids
.
get
(
id
);
if
(
notification
==
null
||
notification
.
param
.
applied_id
!=
id
)
{
return
null
;
}
unowned
AnimatedListItem
?
item
=
(
AnimatedListItem
?)
notification
.
get_parent
();
if
(
item
==
null
||
item
.
destroying
)
{
return
null
;
}
return
notification
;
}
/**
/**
* Hides all notifications. Only invokes the NotificationClosed signal when transient.
* Hides all notifications. Only invokes the NotificationClosed signal when transient.
* The optional callback is used to remove select notifications where each
* The optional callback is used to remove select notifications where each
...
@@ -221,6 +235,7 @@ namespace SwayNotificationCenter {
...
@@ -221,6 +235,7 @@ namespace SwayNotificationCenter {
*/
*/
public
void
remove_all_notifications
(
bool
transition
,
public
void
remove_all_notifications
(
bool
transition
,
notification_filter_func
?
filter_func
)
{
notification_filter_func
?
filter_func
)
{
notification_ids
.
clear
();
inline_reply_notifications
.
clear
();
inline_reply_notifications
.
clear
();
foreach
(
unowned
AnimatedListItem
item
in
list
.
children
)
{
foreach
(
unowned
AnimatedListItem
item
in
list
.
children
)
{
if
(
item
.
destroying
)
{
if
(
item
.
destroying
)
{
...
@@ -240,6 +255,7 @@ namespace SwayNotificationCenter {
...
@@ -240,6 +255,7 @@ namespace SwayNotificationCenter {
return_if_fail
(
notification
!=
null
);
return_if_fail
(
notification
!=
null
);
NotifyParams
param
=
notification
.
param
;
NotifyParams
param
=
notification
.
param
;
notification_ids
.
unset
(
param
.
applied_id
);
// Disable transitions when not mapped
// Disable transitions when not mapped
transition
&=
get_mapped
();
transition
&=
get_mapped
();
...
@@ -285,35 +301,30 @@ namespace SwayNotificationCenter {
...
@@ -285,35 +301,30 @@ namespace SwayNotificationCenter {
set_visible
(
true
);
set_visible
(
true
);
list
.
append
.
begin
(
noti
);
list
.
append
.
begin
(
noti
);
notification_ids
.
set
(
param
.
applied_id
,
noti
);
}
}
/** Removes the notification widget with ID. Doesn't dismiss */
/** Removes the notification widget with ID. Doesn't dismiss */
public
void
remove_notification
(
uint32
id
)
{
public
void
remove_notification
(
uint32
id
)
{
foreach
(
unowned
AnimatedListItem
item
in
list
.
children
)
{
unowned
Notification
?
notification
=
find_notification
(
id
);
if
(
item
.
destroying
)
{
if
(
notification
!=
null
)
{
continue
;
remove_notification_internal
(
notification
,
true
);
}
unowned
Notification
notification
=
(
Notification
)
item
.
child
;
if
(
notification
!=
null
&&
notification
.
param
.
applied_id
==
id
)
{
remove_notification_internal
(
notification
,
true
);
break
;
}
}
}
}
}
public
void
replace_notification
(
uint32
id
,
NotifyParams
new_params
)
{
public
void
replace_notification
(
uint32
id
,
NotifyParams
new_params
)
{
foreach
(
unowned
AnimatedListItem
item
in
list
.
children
)
{
unowned
Notification
?
notification
=
find_notification
(
id
);
if
(
item
.
destroying
)
{
if
(
notification
!=
null
)
{
continue
;
// Replace the ID, could be changed depending on the
}
// replacement method used
var
noti
=
(
Notification
)
item
.
child
;
notification_ids
.
unset
(
id
)
;
if
(
noti
!=
null
&&
noti
.
param
.
applied_id
==
id
)
{
notification_ids
.
set
(
new_params
.
applied_id
,
notification
);
noti
.
replace_notification
(
new_params
);
// Position the notification in the beginning/end of the list
notification
.
replace_notification
(
new_params
);
// and scroll to the new item
// Position the notification in the beginning/end of the list
list
.
move_to_beginning
(
noti
,
true
);
// and scroll to the new item
return
;
list
.
move_to_beginning
(
notification
,
true
)
;
}
return
;
}
}
// Display a new notification if the old one isn't visible
// Display a new notification if the old one isn't visible
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment