Skip to content

Commit

Permalink
wm/win: don't cache window monitor
Browse files Browse the repository at this point in the history
We need to update which monitor a window is on when either the window
position/geometry changes, or when monitor configuration changes. We
only did former.

We could fix that by also doing the latter. But there isn't that much
point in caching the monitor anyway, so let's just calculate it when
needed.

Signed-off-by: Yuxuan Shui <[email protected]>
  • Loading branch information
yshui committed Jun 27, 2024
1 parent 04f602f commit 732f365
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 32 deletions.
3 changes: 0 additions & 3 deletions src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,6 @@ static void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
w->pending_g.border_width = ce->border_width;
win_set_flags(w, WIN_FLAGS_SIZE_STALE);
}

// Recalculate which monitor this window is on
win_update_monitor(&ps->monitors, w);
}

// override_redirect flag cannot be changed after window creation, as far
Expand Down
26 changes: 14 additions & 12 deletions src/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -1121,18 +1121,20 @@ void paint_all(session_t *ps, struct win *t) {
pixman_region32_subtract(&reg_tmp, &reg_tmp, &bshape_no_corners);
}

if (ps->o.crop_shadow_to_monitor && w->randr_monitor >= 0 &&
w->randr_monitor < ps->monitors.count) {
// There can be a window where number of monitors is
// updated, but the monitor number attached to the window
// have not.
//
// Window monitor number will be updated eventually, so
// here we just check to make sure we don't access out of
// bounds.
pixman_region32_intersect(
&reg_tmp, &reg_tmp,
&ps->monitors.regions[w->randr_monitor]);
if (ps->o.crop_shadow_to_monitor) {
auto monitor_index = win_find_monitor(&ps->monitors, w);
if (monitor_index >= 0) {
// There can be a window where number of monitors
// is updated, but the monitor number attached to
// the window have not.
//
// Window monitor number will be updated
// eventually, so here we just check to make sure
// we don't access out of bounds.
pixman_region32_intersect(
&reg_tmp, &reg_tmp,
&ps->monitors.regions[monitor_index]);
}
}

// Detect if the region is empty before painting
Expand Down
9 changes: 6 additions & 3 deletions src/renderer/command_builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,12 @@ command_for_shadow(struct layer *layer, struct backend_command *cmd,
}
}
log_region(TRACE, &cmd->target_mask);
if (monitors && w->randr_monitor >= 0 && w->randr_monitor < monitors->count) {
pixman_region32_intersect(&cmd->target_mask, &cmd->target_mask,
&monitors->regions[w->randr_monitor]);
if (monitors) {
auto monitor_index = win_find_monitor(monitors, w);
if (monitor_index >= 0) {
pixman_region32_intersect(&cmd->target_mask, &cmd->target_mask,
&monitors->regions[monitor_index]);
}
}
log_region(TRACE, &cmd->target_mask);
if (w->corner_radius > 0) {
Expand Down
19 changes: 8 additions & 11 deletions src/wm/win.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,6 @@ void win_process_update_flags(session_t *ps, struct win *w) {
damaged = true;
win_clear_flags(w, WIN_FLAGS_POSITION_STALE);
}

win_update_monitor(&ps->monitors, w);
}

if (win_check_flags_all(w, WIN_FLAGS_PROPERTY_STALE)) {
Expand Down Expand Up @@ -1401,7 +1399,6 @@ struct win *win_maybe_allocate(session_t *ps, struct wm_ref *cursor) {
.focused_force = UNSET,
.invert_color_force = UNSET,

.randr_monitor = -1,
.mode = WMODE_TRANS,
.leader = XCB_NONE,
.cache_leader = XCB_NONE,
Expand Down Expand Up @@ -1983,9 +1980,10 @@ void unmap_win_start(struct win *w) {
}

struct win_script_context win_script_context_prepare(struct session *ps, struct win *w) {
auto monitor_index = win_find_monitor(&ps->monitors, w);
auto monitor =
(w->randr_monitor >= 0 && w->randr_monitor < ps->monitors.count)
? *pixman_region32_extents(&ps->monitors.regions[w->randr_monitor])
monitor_index >= 0
? *pixman_region32_extents(&ps->monitors.regions[monitor_index])
: (pixman_box32_t){
.x1 = 0, .y1 = 0, .x2 = ps->root_width, .y2 = ps->root_height};
struct win_script_context ret = {
Expand Down Expand Up @@ -2158,24 +2156,23 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d

#undef WSTATE_PAIR

// TODO(absolutelynothelix): rename to x_update_win_(randr_?)monitor and move to
// the x.c.
void win_update_monitor(struct x_monitors *monitors, struct win *mw) {
mw->randr_monitor = -1;
/// Find which monitor a window is on.
int win_find_monitor(const struct x_monitors *monitors, const struct win *mw) {
int ret = -1;
for (int i = 0; i < monitors->count; i++) {
auto e = pixman_region32_extents(&monitors->regions[i]);
if (e->x1 <= mw->g.x && e->y1 <= mw->g.y &&
e->x2 >= mw->g.x + mw->widthb && e->y2 >= mw->g.y + mw->heightb) {
mw->randr_monitor = i;
log_debug("Window %#010x (%s), %dx%d+%dx%d, is entirely on the "
"monitor %d (%dx%d+%dx%d)",
win_id(mw), mw->name, mw->g.x, mw->g.y, mw->widthb,
mw->heightb, i, e->x1, e->y1, e->x2 - e->x1, e->y2 - e->y1);
return;
return i;
}
}
log_debug("Window %#010x (%s), %dx%d+%dx%d, is not entirely on any monitor",
win_id(mw), mw->name, mw->g.x, mw->g.y, mw->widthb, mw->heightb);
return ret;
}

/// Start the mapping of a window. We cannot map immediately since we might need to fade
Expand Down
4 changes: 1 addition & 3 deletions src/wm/win.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ struct win {
struct win_geometry g;
/// Updated geometry received in events
struct win_geometry pending_g;
/// X RandR monitor this window is on.
int randr_monitor;
/// Window visual pict format
const xcb_render_pictforminfo_t *pictfmt;
/// Client window visual pict format
Expand Down Expand Up @@ -372,7 +370,7 @@ void win_on_client_update(session_t *ps, struct win *w);

bool attr_pure win_should_dim(session_t *ps, const struct win *w);

void win_update_monitor(struct x_monitors *monitors, struct win *mw);
int attr_pure win_find_monitor(const struct x_monitors *monitors, const struct win *mw);

/// Recheck if a window is fullscreen
void win_update_is_fullscreen(const session_t *ps, struct win *w);
Expand Down

0 comments on commit 732f365

Please sign in to comment.