Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 66 additions & 41 deletions video/out/w32_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,26 +320,6 @@ static LRESULT borderless_nchittest(struct vo_w32_state *w32, int x, int y)
return HTCLIENT;
}

// turn a WMSZ_* input value in v into the border that should be resized
// take into consideration which borders are snapped to avoid detaching
// returns: 0=left, 1=top, 2=right, 3=bottom, -1=undefined
static int get_resize_border(struct vo_w32_state *w32, int v)
{
switch (v) {
case WMSZ_LEFT:
case WMSZ_RIGHT:
return w32->snapped_bottom ? 1 : 3;
case WMSZ_TOP:
case WMSZ_BOTTOM:
return w32->snapped_right ? 0 : 2;
case WMSZ_TOPLEFT: return 1;
case WMSZ_TOPRIGHT: return 1;
case WMSZ_BOTTOMLEFT: return 3;
case WMSZ_BOTTOMRIGHT: return 3;
default: return -1;
}
}

static bool key_state(int vk)
{
return GetKeyState(vk) & 0x8000;
Expand Down Expand Up @@ -1264,6 +1244,68 @@ static void update_ime_enabled(struct vo_w32_state *w32, bool enable)
}
}

static void handle_sizing(struct vo_w32_state *w32, int edge, RECT *rc)
{
RECT wa = get_working_area(w32);
RECT wr;
if (GetWindowRect(w32->window, &wr))
adjust_working_area_for_extended_frame(&wa, &wr, w32->window);

bool drag_l = edge == WMSZ_LEFT || edge == WMSZ_TOPLEFT || edge == WMSZ_BOTTOMLEFT;
bool drag_r = edge == WMSZ_RIGHT || edge == WMSZ_TOPRIGHT || edge == WMSZ_BOTTOMRIGHT;
bool drag_t = edge == WMSZ_TOP || edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT;
bool drag_b = edge == WMSZ_BOTTOM || edge == WMSZ_BOTTOMLEFT || edge == WMSZ_BOTTOMRIGHT;

// Clamp to working area
if (drag_l)
rc->left = MPMAX(rc->right - rect_w(wa), rc->left);
if (drag_r)
rc->right = MPMIN(rc->left + rect_w(wa), rc->right);
if (drag_t)
rc->top = MPMAX(rc->bottom - rect_h(wa), rc->top);
if (drag_b)
rc->bottom = MPMIN(rc->top + rect_h(wa), rc->bottom);

// Windows added title-bar docking (drag top edge to the top of working area),
// and it seems to send WM_SIZING with edge (wParam) set to 9 when undocking
// the window by dragging. This is not documented, and not even an WMSZ_*
// value in 10.0.26100.7705 SDK. However, it does restore window size before
// docking, so we don't have to do anything here.
if (!drag_l && !drag_r && !drag_t && !drag_b)
return;

bool keep_aspect = w32->opts->keepaspect && w32->opts->keepaspect_window;
if (!keep_aspect || !w32->o_dwidth || !w32->o_dheight)
return;

RECT wb = {0};
add_window_borders(w32, w32->window, &wb);
LONG max_w = rect_w(wa) - rect_w(wb), max_h = rect_h(wa) - rect_h(wb);
LONG c_w = rect_w(*rc) - rect_w(wb), c_h = rect_h(*rc) - rect_h(wb);
if ((drag_t || drag_b) && !drag_l && !drag_r) {
c_w = c_h * w32->o_dwidth / w32->o_dheight;
if (c_w > max_w) {
c_w = max_w;
c_h = c_w * w32->o_dheight / w32->o_dwidth;
}
} else {
c_h = c_w * w32->o_dheight / w32->o_dwidth;
if (c_h > max_h) {
c_h = max_h;
c_w = c_h * w32->o_dwidth / w32->o_dheight;
}
}
LONG w_w = c_w + rect_w(wb), w_h = c_h + rect_h(wb);
if (drag_l || (!drag_r && w32->snapped_right))
rc->left = rc->right - w_w;
else
rc->right = rc->left + w_w;
if (drag_t || (!drag_b && w32->snapped_bottom))
rc->top = rc->bottom - w_h;
else
rc->bottom = rc->top + w_h;
}

static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
Expand Down Expand Up @@ -1408,27 +1450,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
break;
}
case WM_SIZING:
if (w32->opts->keepaspect && w32->opts->keepaspect_window &&
!w32->current_fs && !w32->parent && w32->o_dwidth && w32->o_dheight)
{
RECT *rc = (RECT*)lParam;
// get client area of the windows if it had the rect rc
// (subtracting the window borders)
RECT r = *rc;
subtract_window_borders(w32, w32->window, &r);
int c_w = rect_w(r), c_h = rect_h(r);
double aspect = w32->o_dwidth / (double)w32->o_dheight;
int d_w = roundl(c_h * aspect - c_w);
int d_h = roundl(c_w / aspect - c_h);
int d_corners[4] = { d_w, d_h, -d_w, -d_h };
int corners[4] = { rc->left, rc->top, rc->right, rc->bottom };
int corner = get_resize_border(w32, wParam);
if (corner >= 0)
corners[corner] -= d_corners[corner];
*rc = (RECT) { corners[0], corners[1], corners[2], corners[3] };
return TRUE;
}
break;
if (w32->parent || w32->current_fs)
break;
handle_sizing(w32, wParam, (RECT *)lParam);
return TRUE;
case WM_DPICHANGED:
update_display_info(w32);

Expand Down
Loading