This activates the new DPI scaling, and stops pretending that every window is per-monitor DPI aware. It uses the GDI scaled surfaces for DPI-unaware windows, instead of the current higher resolution surfaces, which gives more blurry results but this is the same as Windows for DPI-unaware cases.
-- v2: win32u: Stop setting DPI_PER_MONITOR_AWARE by default. explorer: Make the desktop thread per-monitor DPI aware. server: Pass window's per-monitor DPI in set_window_pos. win32u: Pass window_from_point dpi to list_children_from_point. win32u: Map rect to window DPI in expose_window_surface. winex11: Map message pos to physical DPI in move_resize_window. winewayland: Remove unnecessary logical to physical DPI mapping.
From: Rémi Bernon rbernon@codeweavers.com
This is now properly handled in win32u and all the drivers are now working with physical DPI coordinates directly.
Note that there's still an additional mapping from Wine (window) to Wayland (surface) coordinates, that is handled by coords_from_window and coords_to_window. --- dlls/winewayland.drv/wayland_pointer.c | 46 ++------------------------ dlls/winewayland.drv/window.c | 2 +- 2 files changed, 3 insertions(+), 45 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 1d8acaeabd2..355fc3b486f 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -74,9 +74,6 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy)
pthread_mutex_unlock(&surface->mutex);
- /* Hardware input events are in physical coordinates. */ - if (!NtUserLogicalToPerMonitorDPIPhysicalPoint(hwnd, &screen)) return; - input.type = INPUT_MOUSE; input.mi.dx = screen.x; input.mi.dy = screen.y; @@ -249,22 +246,19 @@ static const struct wl_pointer_listener pointer_listener = };
static void relative_pointer_v1_relative_motion(void *data, - struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, + struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, uint32_t utime_hi, uint32_t utime_lo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel) { INPUT input = {0}; HWND hwnd; - POINT screen, origin; + POINT screen; struct wayland_surface *surface; - RECT window_rect;
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; if (!(surface = wayland_surface_lock_hwnd(hwnd))) return;
- window_rect = surface->window.rect; - wayland_surface_coords_to_window(surface, wl_fixed_to_double(dx), wl_fixed_to_double(dy), @@ -272,42 +266,6 @@ static void relative_pointer_v1_relative_motion(void *data,
pthread_mutex_unlock(&surface->mutex);
- /* We clip the relative motion within the window rectangle so that - * the NtUserLogicalToPerMonitorDPIPhysicalPoint calls later succeed. - * TODO: Avoid clipping by using a more versatile dpi mapping function. */ - if (screen.x >= 0) - { - origin.x = window_rect.left; - screen.x += origin.x; - if (screen.x >= window_rect.right) screen.x = window_rect.right - 1; - } - else - { - origin.x = window_rect.right; - screen.x += origin.x; - if (screen.x < window_rect.left) screen.x = window_rect.left; - } - - if (screen.y >= 0) - { - origin.y = window_rect.top; - screen.y += origin.y; - if (screen.y >= window_rect.bottom) screen.y = window_rect.bottom - 1; - } - else - { - origin.y = window_rect.bottom; - screen.y += origin.y; - if (screen.y < window_rect.top) screen.y = window_rect.top; - } - - /* Transform the relative motion from window coordinates to physical - * coordinates required for the input event. */ - if (!NtUserLogicalToPerMonitorDPIPhysicalPoint(hwnd, &screen)) return; - if (!NtUserLogicalToPerMonitorDPIPhysicalPoint(hwnd, &origin)) return; - screen.x -= origin.x; - screen.y -= origin.y; - input.type = INPUT_MOUSE; input.mi.dx = screen.x; input.mi.dy = screen.y; diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 73a8de37f77..a6285ab592c 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -184,7 +184,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data, }
conf->state = window_state; - conf->scale = NtUserGetDpiForWindow(data->hwnd) / 96.0; + conf->scale = get_win_monitor_dpi(data->hwnd) / 96.0; conf->visible = (style & WS_VISIBLE) == WS_VISIBLE; conf->managed = data->managed; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/mouse.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index ee0191630f7..5941eabd5d0 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -1461,7 +1461,10 @@ void move_resize_window( HWND hwnd, int dir ) if (!(win = X11DRV_get_whole_window( hwnd ))) return;
pt = NtUserGetThreadInfo()->message_pos; - pos = virtual_screen_to_root( (short)LOWORD( pt ), (short)HIWORD( pt ) ); + pos.x = (short)LOWORD( pt ); + pos.y = (short)HIWORD( pt ); + NtUserLogicalToPerMonitorDPIPhysicalPoint( hwnd, &pos ); + pos = virtual_screen_to_root( pos.x, pos.y );
if (NtUserGetKeyState( VK_LBUTTON ) & 0x8000) button = 1; else if (NtUserGetKeyState( VK_MBUTTON ) & 0x8000) button = 2;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 05a353ae53a..393a7797b6f 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2141,6 +2141,7 @@ static BOOL expose_window_surface( HWND hwnd, UINT flags, const RECT *rect, UINT { struct window_surface *surface; struct window_rects rects; + RECT window_rect; HRGN region = 0; WND *win;
@@ -2149,14 +2150,16 @@ static BOOL expose_window_surface( HWND hwnd, UINT flags, const RECT *rect, UINT rects = win->rects; release_win_ptr( win );
+ if (rect) window_rect = map_dpi_rect( *rect, dpi, get_dpi_for_window( hwnd ) ); + if (surface) { window_surface_lock( surface );
- if (!rect) add_bounds_rect( &surface->bounds, rect ); + if (!rect) add_bounds_rect( &surface->bounds, &surface->rect ); else { - RECT dirty = *rect; + RECT dirty = window_rect; OffsetRect( &dirty, rects.client.left - rects.visible.left, rects.client.top - rects.visible.top ); if (!(region = expose_window_surface_rect( surface, flags, dirty ))) flags = 0; else NtGdiOffsetRgn( region, rects.client.left - rects.visible.left, rects.client.top - rects.visible.top ); @@ -2168,7 +2171,7 @@ static BOOL expose_window_surface( HWND hwnd, UINT flags, const RECT *rect, UINT window_surface_release( surface ); }
- if (flags) NtUserRedrawWindow( hwnd, rect, region, flags ); + if (flags) NtUserRedrawWindow( hwnd, rect ? &window_rect : NULL, region, flags ); if (region) NtGdiDeleteObjectApp( region ); return TRUE; }
From: Rémi Bernon rbernon@codeweavers.com
It may be per-monitor, which window_from_point checks but not list_children_from_point. --- dlls/win32u/window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 393a7797b6f..2533582584d 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2435,7 +2435,7 @@ done: * Point is in screen coordinates. * Returned list must be freed by caller. */ -static HWND *list_children_from_point( HWND hwnd, POINT pt ) +static HWND *list_children_from_point( HWND hwnd, POINT pt, UINT dpi ) { int i, size = 128; HWND *list; @@ -2451,7 +2451,7 @@ static HWND *list_children_from_point( HWND hwnd, POINT pt ) req->parent = wine_server_user_handle( hwnd ); req->x = pt.x; req->y = pt.y; - req->dpi = get_thread_dpi(); + req->dpi = dpi; wine_server_set_reply( req, list, (size-1) * sizeof(user_handle_t) ); if (!wine_server_call( req )) count = reply->count; } @@ -2488,7 +2488,7 @@ HWND window_from_point( HWND hwnd, POINT pt, INT *hittest )
*hittest = HTNOWHERE;
- if (!(list = list_children_from_point( hwnd, pt ))) return 0; + if (!(list = list_children_from_point( hwnd, pt, dpi ))) return 0;
/* now determine the hittest */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 1 + server/protocol.def | 1 + server/window.c | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 2533582584d..d45a6925488 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2008,6 +2008,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru req->handle = wine_server_user_handle( hwnd ); req->previous = wine_server_user_handle( insert_after ); req->swp_flags = swp_flags; + req->monitor_dpi = monitor_dpi; req->window = wine_server_rectangle( new_rects->window ); req->client = wine_server_rectangle( new_rects->client ); if (!EqualRect( &new_rects->window, &new_rects->visible ) || new_surface || valid_rects) diff --git a/server/protocol.def b/server/protocol.def index 2c791cbdd46..f260bae2d21 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2592,6 +2592,7 @@ enum message_type @REQ(set_window_pos) unsigned short swp_flags; /* SWP_* flags */ unsigned short paint_flags; /* paint flags (see below) */ + unsigned int monitor_dpi; /* DPI of the window's monitor */ user_handle_t handle; /* handle to the window */ user_handle_t previous; /* previous window in Z order */ rectangle_t window; /* window rectangle (in parent coords) */ diff --git a/server/window.c b/server/window.c index 564c69bf18d..16c2656b8f2 100644 --- a/server/window.c +++ b/server/window.c @@ -84,6 +84,7 @@ struct window unsigned int alpha; /* alpha value for a layered window */ unsigned int layered_flags; /* flags for a layered window */ unsigned int dpi_context; /* DPI awareness context */ + unsigned int monitor_dpi; /* DPI of the window monitor */ lparam_t user_data; /* user-specific data */ WCHAR *text; /* window caption text */ data_size_t text_len; /* length of window caption */ @@ -245,20 +246,17 @@ static inline void update_pixel_format_flags( struct window *win ) win->paint_flags |= PAINT_PIXEL_FORMAT_CHILD; }
-static unsigned int get_window_dpi( struct window *win ) +/* get the per-monitor DPI for a window */ +static unsigned int get_monitor_dpi( struct window *win ) { - unsigned int dpi; - if ((dpi = NTUSER_DPI_CONTEXT_GET_DPI( win->dpi_context ))) return dpi; - /* FIXME: return the window monitor DPI? */ - return USER_DEFAULT_SCREEN_DPI; + while (win->parent && !is_desktop_window( win->parent )) win = win->parent; + return win->monitor_dpi; }
-/* get the per-monitor DPI for a window */ -static unsigned int get_monitor_dpi( struct window *win ) +static unsigned int get_window_dpi( struct window *win ) { - /* FIXME: we return the desktop window DPI for now */ - while (!is_desktop_window( win )) win = win->parent; - return get_window_dpi( win ); + if (NTUSER_DPI_CONTEXT_IS_MONITOR_AWARE( win->dpi_context )) return get_monitor_dpi( win ); + return NTUSER_DPI_CONTEXT_GET_DPI( win->dpi_context ); }
/* link a window at the right place in the siblings list */ @@ -578,6 +576,7 @@ static struct window *create_window( struct window *parent, struct window *owner win->is_layered = 0; win->is_orphan = 0; win->dpi_context = NTUSER_DPI_PER_MONITOR_AWARE; + win->monitor_dpi = USER_DEFAULT_SCREEN_DPI; win->user_data = 0; win->text = NULL; win->text_len = 0; @@ -2476,6 +2475,7 @@ DECL_HANDLER(set_window_pos) win->paint_flags = (win->paint_flags & ~PAINT_CLIENT_FLAGS) | (req->paint_flags & PAINT_CLIENT_FLAGS); if (win->paint_flags & PAINT_HAS_PIXEL_FORMAT) update_pixel_format_flags( win );
+ win->monitor_dpi = req->monitor_dpi; set_window_pos( win, previous, flags, &window_rect, &client_rect, &visible_rect, &surface_rect, &valid_rect );
From: Rémi Bernon rbernon@codeweavers.com
--- programs/explorer/desktop.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 8bed403ac4e..f6545bfaae9 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -1148,6 +1148,8 @@ void manage_desktop( WCHAR *arg ) HANDLE thread; DWORD id;
+ SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ); + /* get the rest of the command line (if any) */ while (*p && !is_whitespace(*p)) p++; if (*p)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/sysparams.c | 52 ++++++++++++----------------------- dlls/win32u/sysparams.c | 1 - dlls/win32u/tests/win32u.c | 10 +++---- 3 files changed, 21 insertions(+), 42 deletions(-)
diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c index 930d6ac6c5b..870b7f1cc93 100644 --- a/dlls/user32/tests/sysparams.c +++ b/dlls/user32/tests/sysparams.c @@ -219,7 +219,7 @@ static DWORD get_real_dpi(void) if (pSetThreadDpiAwarenessContext) { ctx = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ); - todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", ctx ); + ok( ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", ctx ); dpi = pGetDpiForSystem(); ok( dpi, "GetDpiForSystem failed\n" ); /* restore process-wide DPI awareness context */ @@ -3831,7 +3831,7 @@ static void test_SetProcessDpiAwarenessContext( ULONG arg ) winetest_push_context( "%#lx", arg );
ctx = pGetThreadDpiAwarenessContext(); - todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx ); + ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
SetLastError( 0xdeadbeef ); ret = pSetProcessDpiAwarenessContext( 0 ); @@ -3874,14 +3874,13 @@ static void test_SetProcessDpiAwarenessContext( ULONG arg ) ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" ); todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "got %#lx\n", GetLastError() ); ctx = pGetThreadDpiAwarenessContext(); - todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx ); + ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
SetLastError( 0xdeadbeef ); ret = pSetProcessDpiAwarenessContext( context ); - todo_wine ok( ret, "SetProcessDpiAwarenessContext failed, error %lu\n", GetLastError() ); - todo_wine ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + ok( ret, "SetProcessDpiAwarenessContext failed, error %lu\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); ctx = pGetThreadDpiAwarenessContext(); - todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( ctx == expect_ctx, "got %p\n", ctx );
for (i = 0; i < ARRAY_SIZE(contexts); i++) @@ -3891,16 +3890,13 @@ static void test_SetProcessDpiAwarenessContext( ULONG arg ) ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" ); ok( GetLastError() == ERROR_ACCESS_DENIED, "got %#lx\n", GetLastError() ); ctx = pGetThreadDpiAwarenessContext(); - todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( ctx == expect_ctx, "got %p\n", ctx ); }
/* thread DPI context overrides process DPI context */ ctx = pGetThreadDpiAwarenessContext(); - todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( ctx == expect_ctx, "got %p\n", ctx ); old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 ); - todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( old_ctx == (DPI_AWARENESS_CONTEXT)ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx ); ctx = pGetThreadDpiAwarenessContext(); ok( ctx == (DPI_AWARENESS_CONTEXT)0x12, "got %p\n", ctx ); @@ -3922,25 +3918,18 @@ static void test_SetProcessDpiAwarenessContext( ULONG arg ) old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006010 ); ok( old_ctx == ctx, "got %p\n", old_ctx ); ctx = pGetThreadDpiAwarenessContext(); - todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( ctx == expect_ctx, "got %p\n", ctx ); old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x80000011 | (real_dpi << 8)) ); - todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( old_ctx == ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx ); ctx = pGetThreadDpiAwarenessContext(); - todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( ctx == expect_ctx, "got %p\n", ctx ); old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000012 ); - todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( old_ctx == ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx ); ctx = pGetThreadDpiAwarenessContext(); - todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( ctx == expect_ctx, "got %p\n", ctx ); old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000022 ); - todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( old_ctx == ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx ); ctx = pGetThreadDpiAwarenessContext(); - todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ) ok( ctx == expect_ctx, "got %p\n", ctx );
winetest_pop_context(); @@ -3957,7 +3946,7 @@ static void test_SetThreadDpiAwarenessContext(void) }
ctx = pGetThreadDpiAwarenessContext(); - todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx ); + ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
old_ctx = pSetThreadDpiAwarenessContext( 0 ); ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" ); @@ -3965,7 +3954,7 @@ static void test_SetThreadDpiAwarenessContext(void) ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" );
old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 ); - todo_wine ok( old_ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", old_ctx ); + ok( old_ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", old_ctx ); ctx = pGetThreadDpiAwarenessContext(); ok( ctx == (DPI_AWARENESS_CONTEXT)0x12, "got %p\n", ctx ); old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x22 ); @@ -4292,12 +4281,10 @@ static void test_dpi_context(void) HDC hdc = GetDC( 0 );
context = pGetThreadDpiAwarenessContext(); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6010, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x6010, "wrong context %p\n", context ); awareness = pGetAwarenessFromDpiAwarenessContext( context ); - todo_wine - ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness ); - todo_wine - ok( !pIsProcessDPIAware(), "already aware\n" ); + ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness ); + ok( !pIsProcessDPIAware(), "already aware\n" ); dpi = pGetDpiForSystem(); todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI) ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi ); @@ -4313,7 +4300,6 @@ static void test_dpi_context(void) ok( !ret, "got %d\n", ret ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ); - todo_wine ok( ret, "got %d\n", ret ); ok( pIsProcessDPIAware(), "not aware\n" ); real_dpi = pGetDpiForSystem(); @@ -4334,11 +4320,9 @@ static void test_dpi_context(void) ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() ); ret = pGetProcessDpiAwarenessInternal( 0, &awareness ); ok( ret, "got %d\n", ret ); - todo_wine ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness ); ret = pGetProcessDpiAwarenessInternal( GetCurrentProcess(), &awareness ); ok( ret, "got %d\n", ret ); - todo_wine ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness ); SetLastError(0xdeadbeef); ret = pGetProcessDpiAwarenessInternal( (HANDLE)0xdeadbeef, &awareness ); @@ -4354,9 +4338,8 @@ static void test_dpi_context(void) ret = pIsProcessDPIAware(); ok(ret, "got %d\n", ret); context = pGetThreadDpiAwarenessContext(); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); awareness = pGetAwarenessFromDpiAwarenessContext( context ); - todo_wine ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness ); SetLastError( 0xdeadbeef ); context = pSetThreadDpiAwarenessContext( 0 ); @@ -4367,9 +4350,8 @@ static void test_dpi_context(void) ok( !context, "got %p\n", context ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE ); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context ); awareness = pGetAwarenessFromDpiAwarenessContext( context ); - todo_wine ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness ); dpi = pGetDpiForSystem(); ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi ); @@ -4406,17 +4388,17 @@ static void test_dpi_context(void) context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006010 ); ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); context = pGetThreadDpiAwarenessContext(); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006011 ); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context ); context = pGetThreadDpiAwarenessContext(); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 ); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context ); context = pSetThreadDpiAwarenessContext( context ); ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context ); context = pGetThreadDpiAwarenessContext(); - todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context ); + ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context );
if (real_dpi != USER_DEFAULT_SCREEN_DPI) test_dpi_stock_objects( hdc ); ReleaseDC( 0, hdc ); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index cd9e2a37e6c..2ed1395de02 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4925,7 +4925,6 @@ void sysparams_init(void)
/* FIXME: what do the DpiScalingVer flags mean? */ get_dword_entry( (union sysparam_all_entry *)&entry_DPISCALINGVER, 0, &dpi_scaling, 0 ); - if (!dpi_scaling) NtUserSetProcessDpiAwarenessContext( NTUSER_DPI_PER_MONITOR_AWARE, 0 );
if (volatile_base_key && dispos == REG_CREATED_NEW_KEY) /* first process, initialize entries */ { diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 3d0061fce96..a125cc9e1ba 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -2049,7 +2049,7 @@ static DWORD get_real_dpi(void) DWORD dpi;
ctx = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ); - todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", ctx ); + ok( ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", ctx ); dpi = GetDpiForSystem(); ok( dpi, "GetDpiForSystem failed\n" ); /* restore process-wide DPI awareness context */ @@ -2077,7 +2077,7 @@ static void test_NtUserSetProcessDpiAwarenessContext( ULONG context ) winetest_push_context( "%#lx", context );
ret = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ); - todo_wine ok( ret == 0x6010, "got %#x\n", ret ); + ok( ret == 0x6010, "got %#x\n", ret );
SetLastError( 0xdeadbeef ); ret = NtUserSetProcessDpiAwarenessContext( 0, 0 ); @@ -2142,12 +2142,11 @@ static void test_NtUserSetProcessDpiAwarenessContext( ULONG context ) ok( ret == 0, "got %#x\n", ret ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() ); ret = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ); - todo_wine ok( ret == 0x6010, "got %#x\n", ret ); + ok( ret == 0x6010, "got %#x\n", ret );
ret = NtUserSetProcessDpiAwarenessContext( context, 0 ); - todo_wine ok( ret == 1, "got %#x\n", ret ); + ok( ret == 1, "got %#x\n", ret ); ret = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ); - todo_wine_if( context != 0x12 ) ok( ret == context, "got %#x\n", ret );
for (i = 0; i < ARRAY_SIZE(contexts); i++) @@ -2155,7 +2154,6 @@ static void test_NtUserSetProcessDpiAwarenessContext( ULONG context ) ret = NtUserSetProcessDpiAwarenessContext( contexts[i], 0 ); ok( !ret, "got %#x\n", ret ); ret = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ); - todo_wine_if( context != 0x12 ) ok( ret == context, "got %#x\n", ret ); }
v2: Added a likely missing DPI mapping in expose_window_surface, although I wasn't able to reproduce the issue for some reason.
I can reproduce it by dragging some other X11 app in front of the window. You may need to turn off the compositor to get proper exposures.
It's better now with your fix, though I'm still getting unexposed 1-pixel horizontal lines, there's probably a rounding error with the expose rectangle coordinates.
Another issue is that builtin applications (e.g. regedit) are now getting scaled, even though they are marked DPI-aware.
Jinoh Kang (@iamahuman) commented about programs/explorer/desktop.c:
HANDLE thread; DWORD id;
- SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 );
We already have dpiAware setting in manifest. I think it's confusing to set mutually inconsistent DPI awareness in two separate places.
I believe this should be just
``` <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness> ```
in explorer.manifest.
Also, in light of @julliard's comment, should we add this to other builtin programs like regedit?
On Mon Sep 2 11:18:40 2024 +0000, Alexandre Julliard wrote:
Another issue is that builtin applications (e.g. regedit) are now getting scaled, even though they are marked DPI-aware.
It seems to me that current Wine builtin applications are only *system* (i.e., legacy) DPI-aware, which is still subject to GDI scaling when e.g., placed on another monitor with different DPI[^1]:
![hub-page-illustrations](/uploads/ffa66108675c5d13716ee21aac0cc919/hub-page-illustrations.png)
This seems weird though, because we don't have true per-monitor DPI support. Shouldn't system DPI awareness enough to get rid of scaling, since we only have only one DPI setting (in winecfg)? This sounds like a bug to me unless I've missed anythibg.
[^1]: https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-appli...