From: Alexander Monakov Date: Thu, 8 Jan 2015 22:18:23 +0000 (+0300) Subject: i3bar: suspend the child when bars are fully obscured X-Git-Tag: 4.9~17 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=f28ce227e354230da4b33c58d53373a71e67b08d;p=i3%2Fi3 i3bar: suspend the child when bars are fully obscured --- diff --git a/i3bar/include/outputs.h b/i3bar/include/outputs.h index e0beae89..bd41e776 100644 --- a/i3bar/include/outputs.h +++ b/i3bar/include/outputs.h @@ -40,6 +40,7 @@ struct i3_output { char* name; /* Name of the output */ bool active; /* If the output is active */ bool primary; /* If it is the primary output */ + bool visible; /* If the bar is visible on this output */ int ws; /* The number of the currently visible ws */ rect rect; /* The rect (relative to the root-win) */ diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 179f8274..6f5f0ca2 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -481,6 +481,39 @@ void handle_button(xcb_button_press_event_t *event) { free(buffer); } +/* + * Handle visibility notifications: when none of the bars are visible, e.g. + * if windows are in full-screen on each output, suspend the child process. + * + */ +static void handle_visibility_notify(xcb_visibility_notify_event_t *event) { + bool visible = (event->state != XCB_VISIBILITY_FULLY_OBSCURED); + int num_visible = 0; + i3_output *output; + + SLIST_FOREACH (output, outputs, slist) { + if (!output->active) { + continue; + } + if (output->bar == event->window) { + if (output->visible == visible) { + return; + } + output->visible = visible; + } + num_visible += output->visible; + } + + if (num_visible == 0) { + stop_child(); + } else if (num_visible == visible) { + /* Wake the child only when transitioning from 0 to 1 visible bar. + * We cannot transition from 0 to 2 or more visible bars at once since + * visibility events are delivered to each window separately */ + cont_child(); + } +} + /* * Adjusts the size of the tray window and alignment of the tray clients by * configuring their respective x coordinates. To be called when mapping or @@ -945,6 +978,10 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) { } switch (type) { + case XCB_VISIBILITY_NOTIFY: + /* Visibility change: a bar is [un]obscured by other window */ + handle_visibility_notify((xcb_visibility_notify_event_t *)event); + break; case XCB_EXPOSE: /* Expose-events happen, when the window needs to be redrawn */ redraw_bars(); @@ -1461,6 +1498,12 @@ void reconfig_windows(bool redraw_bars) { * */ values[2] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; + if (config.hide_on_modifier == M_DOCK) { + /* If the bar is normally visible, catch visibility change events to suspend + * the status process when the bar is obscured by full-screened windows. */ + values[2] |= XCB_EVENT_MASK_VISIBILITY_CHANGE; + walk->visible = true; + } if (!config.disable_ws) { values[2] |= XCB_EVENT_MASK_BUTTON_PRESS; }