From 2d1c487410ca9420738276692db2af8083be49ea Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Mon, 6 Nov 2023 21:37:39 -0800 Subject: [PATCH] Implement window borders on Windows and treat window position as referring to the client area. It seems unlike GTK, the menu is counted as part of the border. --- include/allegro5/platform/aintwin.h | 1 + src/win/d3d_disp.cpp | 1 + src/win/wgl_disp.c | 1 + src/win/wwindow.c | 40 ++++++++++++++++++++++++++--- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/include/allegro5/platform/aintwin.h b/include/allegro5/platform/aintwin.h index 944b9d6a8..a2b6a93fe 100644 --- a/include/allegro5/platform/aintwin.h +++ b/include/allegro5/platform/aintwin.h @@ -195,6 +195,7 @@ void _al_win_destroy_display_icons(ALLEGRO_DISPLAY *display); /* window decorations */ void _al_win_set_window_position(HWND window, int x, int y); void _al_win_get_window_position(HWND window, int *x, int *y); +bool _al_win_get_window_borders(ALLEGRO_DISPLAY *display, int *left, int *top, int *right, int *bottom); bool _al_win_set_window_constraints(ALLEGRO_DISPLAY *display, int min_w, int min_h, int max_w, int max_h); bool _al_win_get_window_constraints(ALLEGRO_DISPLAY *display, int *min_w, int *min_h, int *max_w, int *max_h); void _al_win_apply_window_constraints(ALLEGRO_DISPLAY *display, bool onoff); diff --git a/src/win/d3d_disp.cpp b/src/win/d3d_disp.cpp index ba236e0c0..8b07330e5 100644 --- a/src/win/d3d_disp.cpp +++ b/src/win/d3d_disp.cpp @@ -2919,6 +2919,7 @@ ALLEGRO_DISPLAY_INTERFACE *_al_display_d3d_driver(void) vt->set_icons = _al_win_set_display_icons; vt->set_window_position = d3d_set_window_position; vt->get_window_position = d3d_get_window_position; + vt->get_window_borders = _al_win_get_window_borders; vt->set_window_constraints = _al_win_set_window_constraints; vt->get_window_constraints = _al_win_get_window_constraints; vt->apply_window_constraints = _al_win_apply_window_constraints; diff --git a/src/win/wgl_disp.c b/src/win/wgl_disp.c index 98255a6b4..92fd3a54a 100644 --- a/src/win/wgl_disp.c +++ b/src/win/wgl_disp.c @@ -1563,6 +1563,7 @@ ALLEGRO_DISPLAY_INTERFACE *_al_display_wgl_driver(void) vt.set_icons = _al_win_set_display_icons; vt.set_window_position = wgl_set_window_position; vt.get_window_position = wgl_get_window_position; + vt.get_window_borders = _al_win_get_window_borders; vt.set_window_constraints = _al_win_set_window_constraints; vt.get_window_constraints = _al_win_get_window_constraints; vt.apply_window_constraints = _al_win_apply_window_constraints; diff --git a/src/win/wwindow.c b/src/win/wwindow.c index 14dcfde8c..ee1634041 100644 --- a/src/win/wwindow.c +++ b/src/win/wwindow.c @@ -206,6 +206,10 @@ HWND _al_win_create_window(ALLEGRO_DISPLAY *display, int width, int height, int width+lsize+rsize, height+tsize+bsize, SWP_NOZORDER | SWP_NOMOVE); + SetWindowPos(my_window, 0, pos_x-lsize, pos_y-tsize, + 0, 0, + SWP_NOZORDER | SWP_NOSIZE); + if (flags & ALLEGRO_FRAMELESS) { SetWindowLong(my_window, GWL_STYLE, WS_VISIBLE); @@ -1192,13 +1196,25 @@ void _al_win_destroy_display_icons(ALLEGRO_DISPLAY *display) DestroyIcon(old_icon); } +static void get_top_left_border(HWND window, int *left, int *top) +{ + WINDOWINFO wi; + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(window, &wi); + + *left = (wi.rcClient.left - wi.rcWindow.left); + *top = (wi.rcClient.top - wi.rcWindow.top); +} + void _al_win_set_window_position(HWND window, int x, int y) { + int left, top; + get_top_left_border(window, &left, &top); SetWindowPos( window, HWND_TOP, - x, - y, + x - left, + y - top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); @@ -1207,13 +1223,15 @@ void _al_win_set_window_position(HWND window, int x, int y) void _al_win_get_window_position(HWND window, int *x, int *y) { RECT r; + int left, top; + get_top_left_border(window, &left, &top); GetWindowRect(window, &r); if (x) { - *x = r.left; + *x = r.left + left; } if (y) { - *y = r.top; + *y = r.top + top; } } @@ -1465,6 +1483,20 @@ int _al_win_determine_adapter(void) return a; } +bool _al_win_get_window_borders(ALLEGRO_DISPLAY *display, int *left, int *top, int *right, int *bottom) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + WINDOWINFO wi; + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(win_display->window, &wi); + + if (left) *left = (wi.rcClient.left - wi.rcWindow.left); + if (top) *top = (wi.rcClient.top - wi.rcWindow.top); + if (right) *right = (wi.rcWindow.right - wi.rcClient.right); + if (bottom) *bottom = (wi.rcWindow.bottom - wi.rcClient.bottom); + return true; +} + /* Function: al_win_add_window_callback */ bool al_win_add_window_callback(ALLEGRO_DISPLAY *display,