@@ -1456,31 +1456,39 @@ public Widget findWidget (Widget widget, long id) {
14561456long foregroundIdleProc (long code , long wParam , long lParam ) {
14571457 if (code >= 0 ) {
14581458 if (!synchronizer .isMessagesEmpty ()) {
1459- sendPostExternalEventDispatchEvent ();
1460- if (runMessagesInIdle ) {
1461- if (runMessagesInMessageProc ) {
1462- OS .PostMessage (hwndMessage , SWT_RUNASYNC , 0 , 0 );
1463- } else {
1464- runAsyncMessages (false );
1459+ // Windows hooks will inherit the thread DPI awareness from
1460+ // the process. Whatever DPI awareness was set before on
1461+ // the thread will be overwritten before the hook is called.
1462+ // This requires to reset the thread DPi awareness to make
1463+ // sure, all UI updates caused by this will be executed
1464+ // with the correct DPI awareness
1465+ runWithProperDPIAwareness (() -> {
1466+ sendPostExternalEventDispatchEvent ();
1467+ if (runMessagesInIdle ) {
1468+ if (runMessagesInMessageProc ) {
1469+ OS .PostMessage (hwndMessage , SWT_RUNASYNC , 0 , 0 );
1470+ } else {
1471+ runAsyncMessages (false );
1472+ }
14651473 }
1466- }
1467- /*
1468- * Bug in Windows. For some reason, input events can be lost
1469- * when a message is posted to the queue from a foreground idle
1470- * hook. The fix is to detect that there are outstanding input
1471- * events and avoid posting the wake event.
1472- *
1473- * Note that PeekMessage() changes the state of events on the
1474- * queue to no longer be considered new. If we peek for input
1475- * events and posted messages (PM_QS_INPUT | PM_QS_POSTMESSAGE),
1476- * it is possible to cause WaitMessage() to sleep until a new
1477- * input event is generated causing sync runnables not to be
1478- * executed.
1479- */
1480- MSG msg = new MSG () ;
1481- int flags = OS .PM_NOREMOVE | OS . PM_NOYIELD | OS . PM_QS_INPUT ;
1482- if (! OS . PeekMessage ( msg , 0 , 0 , 0 , flags )) wakeThread ();
1483- sendPreExternalEventDispatchEvent ( );
1474+ /*
1475+ * Bug in Windows. For some reason, input events can be lost
1476+ * when a message is posted to the queue from a foreground idle
1477+ * hook. The fix is to detect that there are outstanding input
1478+ * events and avoid posting the wake event.
1479+ *
1480+ * Note that PeekMessage() changes the state of events on the
1481+ * queue to no longer be considered new. If we peek for input
1482+ * events and posted messages (PM_QS_INPUT | PM_QS_POSTMESSAGE),
1483+ * it is possible to cause WaitMessage() to sleep until a new
1484+ * input event is generated causing sync runnables not to be
1485+ * executed.
1486+ */
1487+ MSG msg = new MSG ();
1488+ int flags = OS . PM_NOREMOVE | OS . PM_NOYIELD | OS . PM_QS_INPUT ;
1489+ if (! OS .PeekMessage ( msg , 0 , 0 , 0 , flags )) wakeThread () ;
1490+ sendPreExternalEventDispatchEvent ();
1491+ } );
14841492 }
14851493 }
14861494 return OS .CallNextHookEx (idleHook , (int )code , wParam , lParam );
@@ -3425,7 +3433,15 @@ long msgFilterProc (long code, long wParam, long lParam) {
34253433 MSG msg = new MSG ();
34263434 int flags = OS .PM_NOREMOVE | OS .PM_NOYIELD | OS .PM_QS_INPUT | OS .PM_QS_POSTMESSAGE ;
34273435 if (!OS .PeekMessage (msg , 0 , 0 , 0 , flags )) {
3428- if (runAsyncMessages (false )) wakeThread ();
3436+ // Windows hooks will inherit the thread DPI awareness from
3437+ // the process. Whatever DPI awareness was set before on
3438+ // the thread will be overwritten before the hook is called.
3439+ // This requires to reset the thread DPi awareness to make
3440+ // sure, all UI updates caused by this will be executed
3441+ // with the correct DPI awareness
3442+ runWithProperDPIAwareness (() -> {
3443+ if (runAsyncMessages (false )) wakeThread ();
3444+ });
34293445 }
34303446 }
34313447 break ;
@@ -5382,4 +5398,18 @@ private boolean setDPIAwareness(int desiredDpiAwareness) {
53825398 return true ;
53835399}
53845400
5401+ private void runWithProperDPIAwareness (Runnable operation ) {
5402+ if (isRescalingAtRuntime ()) {
5403+ // refreshing is only necessary, when monitor specific scaling is active
5404+ long previousDPIAwareness = OS .GetThreadDpiAwarenessContext ();
5405+ if (!setDPIAwareness (OS .DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 )) {
5406+ // awareness was not changed, so no need to reset it
5407+ previousDPIAwareness = 0 ;
5408+ }
5409+ operation .run ();
5410+ if (previousDPIAwareness > 0 ) {
5411+ OS .SetThreadDpiAwarenessContext (previousDPIAwareness );
5412+ }
5413+ }
5414+ }
53855415}
0 commit comments