Window movement and resizing clamped to prevent moving them entirely offscreen.
This commit is contained in:
parent
1e4951c4cb
commit
0cede78932
3 changed files with 74 additions and 11 deletions
46
dvx/dvxApp.c
46
dvx/dvxApp.c
|
|
@ -770,7 +770,7 @@ static void dispatchEvents(AppContextT *ctx) {
|
||||||
// Handle active drag
|
// Handle active drag
|
||||||
if (ctx->stack.dragWindow >= 0) {
|
if (ctx->stack.dragWindow >= 0) {
|
||||||
if (buttons & 1) {
|
if (buttons & 1) {
|
||||||
wmDragMove(&ctx->stack, &ctx->dirty, mx, my);
|
wmDragMove(&ctx->stack, &ctx->dirty, mx, my, ctx->display.width, ctx->display.height);
|
||||||
} else {
|
} else {
|
||||||
wmDragEnd(&ctx->stack);
|
wmDragEnd(&ctx->stack);
|
||||||
}
|
}
|
||||||
|
|
@ -2782,21 +2782,39 @@ static void pollKeyboard(AppContextT *ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->kbMoveResize.mode == KbModeMoveE) {
|
if (ctx->kbMoveResize.mode == KbModeMoveE) {
|
||||||
|
int32_t oldX = kbWin->x;
|
||||||
|
int32_t oldY = kbWin->y;
|
||||||
|
|
||||||
if (ascii == 0 && scancode == 0x48) {
|
if (ascii == 0 && scancode == 0x48) {
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
|
||||||
kbWin->y -= KB_MOVE_STEP;
|
kbWin->y -= KB_MOVE_STEP;
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
|
||||||
} else if (ascii == 0 && scancode == 0x50) {
|
} else if (ascii == 0 && scancode == 0x50) {
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
|
||||||
kbWin->y += KB_MOVE_STEP;
|
kbWin->y += KB_MOVE_STEP;
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
|
||||||
} else if (ascii == 0 && scancode == 0x4B) {
|
} else if (ascii == 0 && scancode == 0x4B) {
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
|
||||||
kbWin->x -= KB_MOVE_STEP;
|
kbWin->x -= KB_MOVE_STEP;
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
|
||||||
} else if (ascii == 0 && scancode == 0x4D) {
|
} else if (ascii == 0 && scancode == 0x4D) {
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
|
||||||
kbWin->x += KB_MOVE_STEP;
|
kbWin->x += KB_MOVE_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp: keep title bar reachable
|
||||||
|
int32_t screenW = ctx->display.width;
|
||||||
|
int32_t screenH = ctx->display.height;
|
||||||
|
int32_t minVisible = 50;
|
||||||
|
|
||||||
|
if (kbWin->y < 0) {
|
||||||
|
kbWin->y = 0;
|
||||||
|
}
|
||||||
|
if (kbWin->y + CHROME_BORDER_WIDTH + CHROME_TITLE_HEIGHT > screenH) {
|
||||||
|
kbWin->y = screenH - CHROME_BORDER_WIDTH - CHROME_TITLE_HEIGHT;
|
||||||
|
}
|
||||||
|
if (kbWin->x + kbWin->w < minVisible) {
|
||||||
|
kbWin->x = minVisible - kbWin->w;
|
||||||
|
}
|
||||||
|
if (kbWin->x > screenW - minVisible) {
|
||||||
|
kbWin->x = screenW - minVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kbWin->x != oldX || kbWin->y != oldY) {
|
||||||
|
dirtyListAdd(&ctx->dirty, oldX, oldY, kbWin->w, kbWin->h);
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2830,6 +2848,18 @@ static void pollKeyboard(AppContextT *ctx) {
|
||||||
newH = kbWin->maxH;
|
newH = kbWin->maxH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clamp to screen boundaries
|
||||||
|
int32_t screenW = ctx->display.width;
|
||||||
|
int32_t screenH = ctx->display.height;
|
||||||
|
|
||||||
|
if (kbWin->x + newW > screenW) {
|
||||||
|
newW = screenW - kbWin->x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kbWin->y + newH > screenH) {
|
||||||
|
newH = screenH - kbWin->y;
|
||||||
|
}
|
||||||
|
|
||||||
if (newW != kbWin->w || newH != kbWin->h) {
|
if (newW != kbWin->w || newH != kbWin->h) {
|
||||||
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
dirtyListAdd(&ctx->dirty, kbWin->x, kbWin->y, kbWin->w, kbWin->h);
|
||||||
kbWin->w = newW;
|
kbWin->w = newW;
|
||||||
|
|
|
||||||
37
dvx/dvxWm.c
37
dvx/dvxWm.c
|
|
@ -1193,18 +1193,33 @@ void wmDragEnd(WindowStackT *stack) {
|
||||||
// we don't need to ask the app to repaint during the drag, just blit from
|
// we don't need to ask the app to repaint during the drag, just blit from
|
||||||
// its buffer at the new position.
|
// its buffer at the new position.
|
||||||
|
|
||||||
void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY) {
|
void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY, int32_t screenW, int32_t screenH) {
|
||||||
if (stack->dragWindow < 0 || stack->dragWindow >= stack->count) {
|
if (stack->dragWindow < 0 || stack->dragWindow >= stack->count) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowT *win = stack->windows[stack->dragWindow];
|
WindowT *win = stack->windows[stack->dragWindow];
|
||||||
|
int32_t minVisible = 50;
|
||||||
|
|
||||||
dirtyListAdd(dl, win->x, win->y, win->w, win->h);
|
dirtyListAdd(dl, win->x, win->y, win->w, win->h);
|
||||||
|
|
||||||
win->x = mouseX - stack->dragOffX;
|
win->x = mouseX - stack->dragOffX;
|
||||||
win->y = mouseY - stack->dragOffY;
|
win->y = mouseY - stack->dragOffY;
|
||||||
|
|
||||||
|
// Clamp: keep title bar reachable
|
||||||
|
if (win->y < 0) {
|
||||||
|
win->y = 0;
|
||||||
|
}
|
||||||
|
if (win->y + CHROME_BORDER_WIDTH + CHROME_TITLE_HEIGHT > screenH) {
|
||||||
|
win->y = screenH - CHROME_BORDER_WIDTH - CHROME_TITLE_HEIGHT;
|
||||||
|
}
|
||||||
|
if (win->x + win->w < minVisible) {
|
||||||
|
win->x = minVisible - win->w;
|
||||||
|
}
|
||||||
|
if (win->x > screenW - minVisible) {
|
||||||
|
win->x = screenW - minVisible;
|
||||||
|
}
|
||||||
|
|
||||||
dirtyListAdd(dl, win->x, win->y, win->w, win->h);
|
dirtyListAdd(dl, win->x, win->y, win->w, win->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2022,6 +2037,11 @@ void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_
|
||||||
newW = maxW;
|
newW = maxW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newX < 0) {
|
||||||
|
newW += newX;
|
||||||
|
newX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (newW >= minW) {
|
if (newW >= minW) {
|
||||||
win->x = newX;
|
win->x = newX;
|
||||||
win->w = newW;
|
win->w = newW;
|
||||||
|
|
@ -2036,6 +2056,10 @@ void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_
|
||||||
newW = maxW;
|
newW = maxW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (win->x + newW > d->width) {
|
||||||
|
newW = d->width - win->x;
|
||||||
|
}
|
||||||
|
|
||||||
if (newW >= minW) {
|
if (newW >= minW) {
|
||||||
win->w = newW;
|
win->w = newW;
|
||||||
appliedX = true;
|
appliedX = true;
|
||||||
|
|
@ -2051,6 +2075,11 @@ void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_
|
||||||
newH = maxH;
|
newH = maxH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newY < 0) {
|
||||||
|
newH += newY;
|
||||||
|
newY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (newH >= minH) {
|
if (newH >= minH) {
|
||||||
win->y = newY;
|
win->y = newY;
|
||||||
win->h = newH;
|
win->h = newH;
|
||||||
|
|
@ -2065,6 +2094,10 @@ void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_
|
||||||
newH = maxH;
|
newH = maxH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (win->y + newH > d->height) {
|
||||||
|
newH = d->height - win->y;
|
||||||
|
}
|
||||||
|
|
||||||
if (newH >= minH) {
|
if (newH >= minH) {
|
||||||
win->h = newH;
|
win->h = newH;
|
||||||
appliedY = true;
|
appliedY = true;
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ int32_t wmResizeEdgeHit(const WindowT *win, int32_t mx, int32_t my);
|
||||||
// event while dragWindow is active. Dirties both the old and new window
|
// event while dragWindow is active. Dirties both the old and new window
|
||||||
// positions. The drag offset (mouse position relative to window origin at
|
// positions. The drag offset (mouse position relative to window origin at
|
||||||
// drag start) is applied so the window tracks the mouse smoothly.
|
// drag start) is applied so the window tracks the mouse smoothly.
|
||||||
void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY);
|
void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY, int32_t screenW, int32_t screenH);
|
||||||
|
|
||||||
// Update window dimensions during an active resize. Enforces MIN_WINDOW_W/H
|
// Update window dimensions during an active resize. Enforces MIN_WINDOW_W/H
|
||||||
// and optional maxW/maxH constraints. Reallocates the content buffer if the
|
// and optional maxW/maxH constraints. Reallocates the content buffer if the
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue