@@ -418,21 +418,39 @@ struct mako_criteria *global_criteria(struct mako_config *config) {
418418 return criteria ;
419419}
420420
421- static void timespec_add (struct timespec * t , int delta_ms ) {
422- static const long ms = 1000000 , s = 1000000000 ;
421+ static void timespec_from_ms (struct timespec * t , long time_ms ) {
422+ static const long ms = 1000000 ;
423423
424- int delta_ms_low = delta_ms % 1000 ;
425- int delta_s_high = delta_ms / 1000 ;
424+ t -> tv_sec = time_ms / 1000 ;
425+ t -> tv_nsec = (time_ms % 1000 ) * ms ;
426+ }
427+
428+ static void timespec_add (struct timespec * t , struct timespec * u ) {
429+ static const long s = 1000000000 ;
426430
427- t -> tv_sec += delta_s_high ;
431+ t -> tv_sec += u -> tv_sec ;
432+ t -> tv_nsec += u -> tv_nsec ;
428433
429- t -> tv_nsec += (long )delta_ms_low * ms ;
430434 if (t -> tv_nsec >= s ) {
431435 t -> tv_nsec -= s ;
432436 ++ t -> tv_sec ;
433437 }
434438}
435439
440+ static void timespec_sub (struct timespec * t , struct timespec * u ) {
441+ static const long s = 1000000000 ;
442+
443+ t -> tv_sec -= u -> tv_sec ;
444+ t -> tv_nsec += s ;
445+ t -> tv_nsec -= u -> tv_nsec ;
446+
447+ if (t -> tv_nsec >= s ) {
448+ t -> tv_nsec -= s ;
449+ } else {
450+ -- t -> tv_sec ;
451+ }
452+ }
453+
436454static void handle_notification_timer (void * data ) {
437455 struct mako_notification * notif = data ;
438456 struct mako_surface * surface = notif -> surface ;
@@ -474,10 +492,25 @@ ssize_t apply_each_criteria(struct mako_state *state, struct mako_notification *
474492 if (expire_timeout < 0 || notif -> style .ignore_timeout ) {
475493 expire_timeout = notif -> style .default_timeout ;
476494 }
495+ if (notif -> frozen != notif -> style .freeze ) {
496+ struct timespec now ;
497+ clock_gettime (CLOCK_MONOTONIC , & now );
498+ if (notif -> style .freeze ) {
499+ notif -> froze_at = now ;
500+ } else {
501+ timespec_sub (& now , & notif -> froze_at );
502+ timespec_add (& notif -> at , & now );
503+ }
504+ notif -> frozen = notif -> style .freeze ;
505+ }
506+ if (notif -> frozen ) {
507+ expire_timeout = 0 ;
508+ }
477509
478510 if (expire_timeout > 0 ) {
479- struct timespec at = notif -> at ;
480- timespec_add (& at , expire_timeout );
511+ struct timespec at = notif -> at , delta ;
512+ timespec_from_ms (& delta , expire_timeout );
513+ timespec_add (& at , & delta );
481514 if (notif -> timer ) {
482515 notif -> timer -> at = at ;
483516 } else {
0 commit comments