FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Redraw damage rectangles by mgrant0 · Pull Request #5516 · tmux/tmux · GitHub

/ tmux Public
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (10) .h  (1) .sh  (11) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
10 changes: 9 additions & 1 deletion cmd-join-pane.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ cmd_join_pane_mouse_move(struct client *c, struct mouse_event *m)
struct window_pane *wp;
struct layout_cell *lc;
int y, ly, x, lx;
int old_xoff, old_yoff, old_sx, old_sy;

wp = cmd_mouse_pane(m, NULL, &wl);
if (wp == NULL) {
Expand All @@ -321,10 +322,17 @@ cmd_join_pane_mouse_move(struct client *c, struct mouse_event *m)
ly = m->statusat - 1;

if (x != lx || y != ly) {
old_xoff = wp->xoff;
old_yoff = wp->yoff;
old_sx = wp->sx;
old_sy = wp->sy;

lc->g.xoff += x - lx;
lc->g.yoff += y - ly;
layout_fix_panes(w, NULL);
server_redraw_window(w);

window_pane_redraw_floating(w, wp, old_xoff, old_yoff, old_sx,
old_sy);
server_redraw_window_borders(w);
}
}
Expand Down
8 changes: 7 additions & 1 deletion cmd-resize-pane.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
int y, ly, x, lx, sx, sy, new_sx, new_sy;
int left, right;
int new_xoff, new_yoff, resizes = 0;
int old_xoff, old_yoff, old_sx, old_sy;

wp = cmd_mouse_pane(m, NULL, &wl);
if (wp == NULL) {
Expand All @@ -247,6 +248,10 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
lc = wp->layout_cell;
sx = wp->sx;
sy = wp->sy;
old_xoff = wp->xoff;
old_yoff = wp->yoff;
old_sx = (int)wp->sx;
old_sy = (int)wp->sy;
left = wp->xoff - 1;
right = wp->xoff + sx;
if (window_pane_scrollbar_reserve(wp) &&
Expand Down Expand Up @@ -346,7 +351,8 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
}
if (resizes != 0) {
layout_fix_panes(w, NULL);
server_redraw_window(w);
window_pane_redraw_floating(w, wp, old_xoff, old_yoff, old_sx,
old_sy);
server_redraw_window_borders(w);
}
}
Expand Down
10 changes: 9 additions & 1 deletion cmd-split-window.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ cmd_split_window_mouse_resize(struct client *c, struct mouse_event *m)
enum pane_lines lines;
u_int sx, sy;
int x, y, xoff, yoff, border;
int old_xoff, old_yoff, old_sx, old_sy;

if (c->tty.mouse_last_pane == -1)
return;
Expand Down Expand Up @@ -415,8 +416,15 @@ cmd_split_window_mouse_resize(struct client *c, struct mouse_event *m)
if (sy < PANE_MINIMUM)
sy = PANE_MINIMUM;

old_xoff = wp->xoff;
old_yoff = wp->yoff;
old_sx = wp->sx;
old_sy = wp->sy;

layout_set_size(lc, sx, sy, xoff, yoff);
layout_fix_panes(w, NULL);
server_redraw_window(w);

window_pane_redraw_floating(w, wp, old_xoff, old_yoff, old_sx,
old_sy);
server_redraw_window_borders(w);
}
6 changes: 4 additions & 2 deletions layout.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -492,16 +492,18 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
sx = PANE_MINIMUM;
else
sx = sx - sb_w - sb_pad;
wp->flags |= PANE_REDRAWSCROLLBAR;
}

window_pane_resize(wp, sx, sy);

if (wp->xoff != old_xoff ||
wp->yoff != old_yoff ||
wp->sx != old_sx ||
wp->sy != old_sy)
wp->sy != old_sy) {
changed = 1;
if (window_pane_scrollbar_reserve(wp))
wp->flags |= PANE_REDRAWSCROLLBAR;
}
}
if (changed)
redraw_invalidate_scene(w);
Expand Down
60 changes: 57 additions & 3 deletions popup.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ popup_reapply_styles(struct popup_data *pd)
}

static void
popup_redraw_cb(const struct tty_ctx *ttyctx)
popup_redraw_cb(const struct tty_ctx *ttyctx, __unused u_int py,
__unused u_int ny)
{
struct popup_data *pd = ttyctx->arg;

Expand Down Expand Up @@ -320,11 +321,60 @@ popup_resize_cb(__unused struct client *c, void *data)
}
}

/*
* Report damage for a popup's rectangle, given in raw client/tty
* coordinates. Status-line cells are outside the window scene - they have no
* corresponding window content and redraw_damage_window() can't reach them -
* so if the popup's rectangle overlaps the status line, force it to redraw
* separately. The rest of the rectangle is clipped to the actual pane area
* (above or below the status line, whichever side it's on) before being
* translated into window coordinates and reported the normal way, the same
* way mouse coordinates are translated elsewhere (e.g. cmd-join-pane.c,
* cmd-split-window.c).
*/
static void
popup_damage(struct client *c, u_int px, u_int py, u_int sx, u_int sy)
{
struct window *w;
int statusat;
u_int ox, oy, osx, osy, lines, top, bottom, y0, y1;

if (c->session == NULL)
return;
w = c->session->curw->window;

lines = status_line_size(c);
statusat = status_at_line(c);
if (statusat >= 0 && py < (u_int)statusat + lines &&
py + sy > (u_int)statusat)
c->flags |= (CLIENT_REDRAWSTATUS|CLIENT_REDRAWSTATUSALWAYS);

if (statusat == 0) {
top = lines;
bottom = c->tty.sy;
} else if (statusat > 0) {
top = 0;
bottom = statusat;
} else {
top = 0;
bottom = c->tty.sy;
}
y0 = (py > top) ? py : top;
y1 = (py + sy < bottom) ? py + sy : bottom;
if (y0 >= y1)
return;

tty_window_offset(&c->tty, &ox, &oy, &osx, &osy);
redraw_damage_window(w, px + ox, y0 - top + oy, sx, y1 - y0);
}

static void
popup_handle_drag(struct client *c, struct popup_data *pd,
struct mouse_event *m)
{
u_int px, py;
u_int old_px = pd->px, old_py = pd->py;
u_int old_sx = pd->sx, old_sy = pd->sy;

if (!MOUSE_DRAG(m->b))
pd->dragging = OFF;
Expand All @@ -347,7 +397,9 @@ popup_handle_drag(struct client *c, struct popup_data *pd,
pd->dy = m->y - pd->py;
pd->ppx = px;
pd->ppy = py;
server_redraw_client(c);

popup_damage(c, old_px, old_py, old_sx, old_sy);
c->flags |= CLIENT_REDRAWOVERLAY;
} else if (pd->dragging == SIZE) {
if (pd->border_lines == BOX_LINES_NONE) {
if (m->x < pd->px + 1)
Expand All @@ -374,7 +426,9 @@ popup_handle_drag(struct client *c, struct popup_data *pd,
if (pd->job != NULL)
job_resize(pd->job, pd->sx - 2, pd->sy - 2);
}
server_redraw_client(c);

popup_damage(c, old_px, old_py, old_sx, old_sy);
c->flags |= CLIENT_REDRAWOVERLAY;
}
}

Expand Down
108 changes: 108 additions & 0 deletions regress/floating-pane-drag-ghost.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/bin/sh

# Regression test for a floating-pane drag bug: cmd_resize_pane_redraw_floating()
# (cmd-resize-pane.c) reported damage for just a dragged floating pane's
# content rectangle, not the one-cell border frame drawn around it (see the
# "floating" case in screen-redraw.c, which draws that frame at
# xoff-1/yoff-1 through xoff+sx/yoff+sy - one cell outside the pane's own
# content area). Damage scoped to only the content area left the frame's
# previous position undrawn as the pane moved, so dragging it left a trail
# of un-erased border frames behind - visible as several "corners" stacked
# up rather than just the pane's current one.
#
# This bug has nothing to do with images - it reproduces with a plain
# floating pane and no image support required.

PATH=/bin:/usr/bin
TERM=screen
LC_ALL=C.UTF-8
export TERM LC_ALL

[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
TMUX2="$TEST_TMUX -LtestB$$ -f/dev/null"

cleanup()
{
$TMUX kill-server >/dev/null 2>&1
$TMUX2 kill-server >/dev/null 2>&1
}
fail()
{
echo "$*" >&2
cleanup
exit 1
}

# drag STARTCOL STARTROW ENDCOL ENDROW
#
# Write a plain (unmodified) SGR button-1 press, drag update and release at
# 1-based positions to the outer pane holding the inner client - this
# matches the default MouseDown1Border/MouseDrag1Border bindings used to
# move or resize a floating pane by its border.
drag()
{
scol="$1"
srow="$2"
ecol="$3"
erow="$4"

seq=$(printf '\033[<0;%s;%sM' "$scol" "$srow")
$TMUX2 send-keys -t "$OUTER" -l "$seq" 2>/dev/null
sleep 0.2
seq=$(printf '\033[<32;%s;%sM' "$ecol" "$erow")
$TMUX2 send-keys -t "$OUTER" -l "$seq" 2>/dev/null
sleep 0.2
seq=$(printf '\033[<0;%s;%sm' "$ecol" "$erow")
$TMUX2 send-keys -t "$OUTER" -l "$seq" 2>/dev/null
sleep 1
}

cleanup

TMP=$(mktemp)
trap "cleanup; rm -f $TMP" 0 1 15

$TMUX new-session -d -s inner -x 60 -y 20 'sh -c "sleep 100"' || exit 1
$TMUX set -g mouse on
$TMUX set -g default-command 'sh -c "sleep 100"'

FLOAT=$($TMUX new-pane -d -PF '#{pane_id}' -x 16 -y 5 -X 5 -Y 5) ||
fail "new-pane -X -Y failed"
FTOP=$($TMUX display-message -p -t "$FLOAT" '#{pane_top}')
FLEFT=$($TMUX display-message -p -t "$FLOAT" '#{pane_left}')
FWIDTH=$($TMUX display-message -p -t "$FLOAT" '#{pane_width}')

$TMUX2 new-session -d -x 60 -y 20 "$TMUX attach -t inner" || exit 1
sleep 1
OUTER=$($TMUX2 list-panes -F '#{pane_id}' | head -1)
[ -n "$OUTER" ] || fail "No outer pane."

# Sanity check: exactly one floating pane, so exactly one top-left corner,
# before dragging anything.
$TMUX2 capturep -p -t "$OUTER" >$TMP || fail "capture failed"
n=$(grep -o '┌' $TMP | wc -l)
[ "$n" -eq 1 ] || fail "sanity: expected 1 corner before drag, found $n"

# Drag the floating pane by its top border (row FTOP-1, some column within
# its width) down several rows in a few separate steps, then release. A
# single drag() call already does press/motion/release, so call it several
# times in a row to simulate a multi-step real drag.
GRABCOL=$((FLEFT + FWIDTH / 2))
STARTROW=$FTOP
i=0
while [ $i -lt 6 ]; do
newrow=$((STARTROW + i + 1))
drag $((GRABCOL + 1)) $((STARTROW + i)) $((GRABCOL + 1)) $newrow
i=$((i + 1))
done

$TMUX2 capturep -p -t "$OUTER" >$TMP || fail "capture failed"

# Exactly one top-left corner should remain - the pane's current position.
# This is expected to fail before the fix: multiple corners (a trail of
# un-erased frames) would remain from the intermediate drag positions.
n=$(grep -o '┌' $TMP | wc -l)
[ "$n" -eq 1 ] || fail "expected exactly 1 corner after drag, found $n (ghost frames left behind)"

exit 0
Loading

Back | FazBrowse Home | New Git URL