When resizing an resizable window, we can resize it smaller than it's
minsize show in Windows, I think it's a bug, and try to fix it.
Signed-off-by: Zhipeng Zhao <near2see(a)163.com>
---
dlls/winex11.drv/mouse.c | 121 +++++++++++++++++++++++++++++++++++++-
dlls/winex11.drv/window.c | 14 ++++-
2 files changed, 131 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 290732fa93..1c5766be09 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -1560,6 +1560,104 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
return TRUE;
}
+/***********************************************************************
+ * set_window_minsize
+ */
+void set_window_minsize(HWND hwnd, RECT* sizingRect, int dir, int* minWidth, int* minHeight)
+{
+ Display *display = thread_display();
+ Window win = X11DRV_get_whole_window( hwnd );
+ POINT pos;
+ GetCursorPos(&pos);
+ switch (dir)
+ {
+ case 7: //_NET_WM_MOVERESIZE_SIZE_LEFT:
+ case 3: //_NET_WM_MOVERESIZE_SIZE_RIGHT:
+ if(*minWidth == 0)
+ {
+ FIXME("before top = %i, left = %i, right = %i, bottom = %i, width = %i\n", sizingRect->top, sizingRect->left, sizingRect->right, sizingRect->bottom, sizingRect->right-sizingRect->left);
+ if(dir == 3)
+ {
+ if(pos.x > sizingRect->right) return;
+ sizingRect->right = pos.x;
+ SendMessageW(hwnd, WM_SIZING, WMSZ_RIGHT, sizingRect);
+ }
+ else if(dir == 7)
+ {
+ if(pos.x < sizingRect->left) return;
+ sizingRect->left = pos.x;
+ SendMessageW(hwnd, WM_SIZING, WMSZ_LEFT, sizingRect);
+ }
+ FIXME("after top = %i, left = %i, right = %i, bottom = %i, width = %i\n", sizingRect->top, sizingRect->left, sizingRect->right, sizingRect->bottom, sizingRect->right-sizingRect->left);
+ if((dir == 3 ? sizingRect->right > pos.x : sizingRect->left < pos.x))
+ {
+ *minWidth = sizingRect->right - sizingRect->left;
+ XSizeHints* sizehints = XAllocSizeHints();
+ LONG ret = -1;
+ XGetWMNormalHints(display, win, sizehints, &ret);
+ sizehints->flags |= PMinSize;
+ sizehints->min_width = *minWidth;
+ XSetWMNormalHints(display, win, sizehints);
+ XFree(sizehints);
+ FIXME("minWidth = %i\n", *minWidth);
+ }
+ }
+ break;
+ case 1: //_NET_WM_MOVERESIZE_SIZE_TOP:
+ case 5: //_NET_WM_MOVERESIZE_SIZE_BOTTOM:
+ if(*minHeight == 0)
+ {
+ FIXME("before top = %i, left = %i, right = %i, bottom = %i, width = %i\n", sizingRect->top, sizingRect->left,
+ sizingRect->right, sizingRect->bottom, sizingRect->right-sizingRect->left);
+ if(dir == 1)
+ {
+ if(pos.y < sizingRect->top) return;
+ sizingRect->top = pos.y;
+ SendMessageW(hwnd, WM_SIZING, WMSZ_TOP, sizingRect);
+ }
+ else if(dir == 5)
+ {
+ if(pos.y > sizingRect->top) return;
+ sizingRect->bottom = pos.y;
+ SendMessageW(hwnd, WM_SIZING, WMSZ_BOTTOM, sizingRect);
+ }
+ FIXME("after top = %i, left = %i, right = %i, bottom = %i, width = %i\n", sizingRect->top, sizingRect->left,
+ sizingRect->right, sizingRect->bottom, sizingRect->right-sizingRect->left);
+ if((dir == 1 ? sizingRect->top < pos.y : sizingRect->bottom > pos.y))
+ {
+ *minHeight = sizingRect->bottom - sizingRect->top;
+ XSizeHints* sizehints = XAllocSizeHints();
+ LONG ret = -1;
+ XGetWMNormalHints(display, win, sizehints, &ret);
+ sizehints->flags |= PMinSize;
+ sizehints->min_height = *minHeight;
+ XSetWMNormalHints(display, win, sizehints);
+ XFree(sizehints);
+ FIXME("minHeight = %i\n", *minHeight);
+ }
+ }
+ break;
+ case 0: //_NET_WM_MOVERESIZE_SIZE_TOPLEFT
+ set_window_minsize(hwnd, sizingRect, 1, minWidth, minHeight);
+ set_window_minsize(hwnd, sizingRect, 7, minWidth, minHeight);
+ break;
+ case 2: //_NET_WM_MOVERESIZE_SIZE_TOPRIGHT
+ set_window_minsize(hwnd, sizingRect, 1, minWidth, minHeight);
+ set_window_minsize(hwnd, sizingRect, 3, minWidth, minHeight);
+ break;
+ case 4: //_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
+ set_window_minsize(hwnd, sizingRect, 5, minWidth, minHeight);
+ set_window_minsize(hwnd, sizingRect, 3, minWidth, minHeight);
+ break;
+ case 6: //_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
+ set_window_minsize(hwnd, sizingRect, 5, minWidth, minHeight);
+ set_window_minsize(hwnd, sizingRect, 7, minWidth, minHeight);
+ break;
+ default:
+ break;
+ }
+}
+
/***********************************************************************
* move_resize_window
*/
@@ -1572,7 +1670,28 @@ void move_resize_window( HWND hwnd, int dir )
XEvent xev;
Window win, root, child;
unsigned int xstate;
+ RECT sizingRect;
+ LONG minWidth = 0;
+ LONG minHeight = 0;
+ MINMAXINFO info;
+ info.ptMinTrackSize.x = 0;
+ info.ptMinTrackSize.y = 0;
+ SendMessageW(hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&info);
+ if(info.ptMinTrackSize.x !=0 && info.ptMinTrackSize.y != 0)
+ {
+ minWidth = info.ptMinTrackSize.x;
+ minHeight = info.ptMinTrackSize.y;
+ XSizeHints* sizehints = XAllocSizeHints();
+ LONG ret = -1;
+ XGetWMNormalHints(display, win, sizehints, &ret);
+ sizehints->flags |= PMinSize;
+ sizehints->min_height = minHeight;
+ sizehints->min_width = minWidth;
+ XSetWMNormalHints(display, win, sizehints);
+ XFree(sizehints);
+ }
+ GetWindowRect( hwnd, &sizingRect);
if (!(win = X11DRV_get_whole_window( hwnd ))) return;
pt = GetMessagePos();
@@ -1629,7 +1748,7 @@ void move_resize_window( HWND hwnd, int dir )
input.u.mi.dwExtraInfo = 0;
__wine_send_input( hwnd, &input );
}
-
+ GetWindowRect( hwnd, &sizingRect);
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
{
if (!CallMsgFilterW( &msg, MSGF_SIZE ))
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 99e4094ebd..dcbebb801b 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -683,13 +683,21 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style )
if (!is_window_resizable( data, style ))
{
+ XSizeHints* sizehints = XAllocSizeHints();
+ long ret = 0;
+ XGetWMNormalHints(data->display, data->whole_window, sizehints, &ret);
size_hints->max_width = data->whole_rect.right - data->whole_rect.left;
size_hints->max_height = data->whole_rect.bottom - data->whole_rect.top;
if (size_hints->max_width <= 0 ||size_hints->max_height <= 0)
size_hints->max_width = size_hints->max_height = 1;
- size_hints->min_width = size_hints->max_width;
- size_hints->min_height = size_hints->max_height;
- size_hints->flags |= PMinSize | PMaxSize;
+ size_hints->flags |= PMaxSize ;
+ if(sizehints->min_height > 0 && sizehints->min_width > 0)
+ {
+ size_hints->min_width = sizehints->min_width;
+ size_hints->min_height = sizehints->min_height;
+ size_hints->flags |= PMinSize;
+ }
+ XFree(sizehints);
}
}
XSetWMNormalHints( data->display, data->whole_window, size_hints );
--
2.24.1.windows.2