Coalesce status publishing into one per event loop pass

9b4187266e38bc6b6d04c18a72bb369d9d61e0e4
Alexis Sellier committed ago 1 parent 0a1fb3c2
swm.c +24 -1
577 577
static void output_manager_test(struct wl_listener *listener, void *data);
578 578
static void pointer_focus(
579 579
    client_t *c, struct wlr_surface *surface, double sx, double sy, uint32_t time, bool refocus
580 580
);
581 581
static void         print_status(void);
582 +
static void         publish_status(void);
583 +
static void         status_idle_notify(void *data);
582 584
static void         publish_windows(const char *runtime);
583 585
static void         prepare_child(void);
584 586
static void         power_manager_set_mode(struct wl_listener *listener, void *data);
585 587
static void         quit(const arg_t *arg);
586 588
static void         raise_client(const arg_t *arg);
665 667
static bool                    locked;
666 668
static void                   *exclusive_focus;
667 669
static struct wl_display      *dpy;
668 670
static struct wl_event_loop   *event_loop;
669 671
static struct wl_event_source *signal_sources[3];
672 +
static struct wl_event_source *status_idle;
670 673
static struct wl_listener     *global_listeners[MAX_GLOBAL_LISTENERS];
671 674
static size_t                  global_listener_count;
672 675
static sigset_t                original_signal_mask;
673 676
static struct wlr_backend     *backend;
674 677
static struct wlr_scene       *scene;
4618 4621
        );
4619 4622
    }
4620 4623
    file_replace_commit(file, tmppath, path);
4621 4624
}
4622 4625
4623 -
/* Publish current display, workspace, and focus state on standard output. */
4626 +
/* Publish the status once the current batch of changes has settled. */
4627 +
void status_idle_notify(void *data) {
4628 +
    status_idle = nullptr;
4629 +
    publish_status();
4630 +
}
4631 +
4632 +
/* Request a status publish. A single change often touches focus, layout and
4633 +
 * workspaces in turn, and each step would otherwise rewrite the state files and
4634 +
 * resend every window's state to taskbars. Coalesce them into one publish at
4635 +
 * the end of the event loop iteration. */
4624 4636
void print_status(void) {
4637 +
    if (status_idle)
4638 +
        return;
4639 +
4640 +
    /* Without an event loop to defer to, publish now. */
4641 +
    if (!event_loop ||
4642 +
        !(status_idle = wl_event_loop_add_idle(event_loop, status_idle_notify, nullptr)))
4643 +
        publish_status();
4644 +
}
4645 +
4646 +
/* Publish current display, workspace, and focus state on standard output. */
4647 +
void publish_status(void) {
4625 4648
    monitor_t  *m = nullptr;
4626 4649
    client_t   *c;
4627 4650
    FILE       *titlefile;
4628 4651
    char        titlepath[MAX_STATE_PATH], tmppath[MAX_STATE_PATH];
4629 4652
    char        title[MAX_STATUS_FIELD], appid[MAX_STATUS_FIELD];