@@ -418,15 +418,38 @@ struct mako_criteria *global_criteria(struct mako_config *config) {
418418 return criteria ;
419419}
420420
421- // Iterate through `criteria_list`, applying the style from each matching
421+ static void timespec_add (struct timespec * t , int delta_ms ) {
422+ static const long ms = 1000000 , s = 1000000000 ;
423+
424+ int delta_ms_low = delta_ms % 1000 ;
425+ int delta_s_high = delta_ms / 1000 ;
426+
427+ t -> tv_sec += delta_s_high ;
428+
429+ t -> tv_nsec += (long )delta_ms_low * ms ;
430+ if (t -> tv_nsec >= s ) {
431+ t -> tv_nsec -= s ;
432+ ++ t -> tv_sec ;
433+ }
434+ }
435+
436+ static void handle_notification_timer (void * data ) {
437+ struct mako_notification * notif = data ;
438+ struct mako_surface * surface = notif -> surface ;
439+ notif -> timer = NULL ;
440+
441+ close_notification (notif , MAKO_NOTIFICATION_CLOSE_EXPIRED , true);
442+ set_dirty (surface );
443+ }
444+
445+ // Iterate through the criteria list, applying the style from each matching
422446// criteria to `notif`. Returns the number of criteria that matched, or -1 if
423447// a failure occurs.
424- ssize_t apply_each_criteria (struct wl_list * criteria_list ,
425- struct mako_notification * notif ) {
448+ ssize_t apply_each_criteria (struct mako_state * state , struct mako_notification * notif ) {
426449 ssize_t match_count = 0 ;
427450
428451 struct mako_criteria * criteria ;
429- wl_list_for_each (criteria , criteria_list , link ) {
452+ wl_list_for_each (criteria , & state -> config . criteria , link ) {
430453 if (!match_criteria (criteria , notif )) {
431454 continue ;
432455 }
@@ -447,6 +470,25 @@ ssize_t apply_each_criteria(struct wl_list *criteria_list,
447470 }
448471 }
449472
473+ int32_t expire_timeout = notif -> requested_timeout ;
474+ if (expire_timeout < 0 || notif -> style .ignore_timeout ) {
475+ expire_timeout = notif -> style .default_timeout ;
476+ }
477+
478+ if (expire_timeout > 0 ) {
479+ struct timespec at = notif -> at ;
480+ timespec_add (& at , expire_timeout );
481+ if (notif -> timer ) {
482+ notif -> timer -> at = at ;
483+ } else {
484+ notif -> timer = add_event_loop_timer (& state -> event_loop , & at ,
485+ handle_notification_timer , notif );
486+ }
487+ } else if (notif -> timer ) {
488+ destroy_timer (notif -> timer );
489+ notif -> timer = NULL ;
490+ }
491+
450492 if (!notif -> surface ) {
451493 notif -> surface = create_surface (notif -> state , notif -> style .output ,
452494 notif -> style .layer , notif -> style .anchor );
0 commit comments