Skip to content

Conversation

amartya4256
Copy link
Contributor

@amartya4256 amartya4256 commented Sep 2, 2025

This PR improves the design implementation for widgets in win32 by moving away from DPIZoomChangeRegistry to an event-driven design using ZoomChanged event and inheritance.

Copy link
Contributor

github-actions bot commented Sep 2, 2025

Test Results

  118 files  ±0    118 suites  ±0   10m 7s ⏱️ -55s
4 431 tests ±0  4 409 ✅  - 5  17 💤 ±0  5 ❌ +5 
  298 runs  ±0    289 ✅  - 5   4 💤 ±0  5 ❌ +5 

For more details on these failures, see this check.

Results for commit d43db71. ± Comparison against base commit 2edab10.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@HeikoKlare HeikoKlare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused by this change, as it introduces a mixture of event processing and direct method calls for DPI change processing. I expected the following order of changes according to what we have discussed:

  1. Replace CommonWidgetsDPIChangeHandler: use listeners instead
  2. Replace DPIZoomChangeRegistry: make direct calls of handleDPIChange for the native controls instead
  3. Replace direct handleDPIChange calls: use listeners instead
  4. Make the listener calls asynchronous (may be combined with the previous step)

This change seems to be a mixture of the first three. Can we please split that up and make the changes in a more incremental, comprehensive way?

@amartya4256
Copy link
Contributor Author

@HeikoKlare I think we have mixed up things. With this PR we just wanted to move to Event driven architecture and not make it asynchronous. I understand that both the terms go hand in hand but we must note that the event model in SWT is synchronous and if an event is sent by a caller, at first the stub is executed and the caller waits for the event to be processed and then moves forward. Hence, this PR doesn't implement asynchrony. That's also the reason why I called notifyListeners instead of calling handleDpiChange because every widget registers to a listener then they must receive the DPI_CHANGE event also through listeners and not by some other widget calling handleDPIChange on them. The follow up PR would implement asynchrony while calling notifyListeners by the following:

void sendZoomChangedEvent(Event event, Shell shell) {
	AtomicInteger handleDPIChangedScheduledTasksCount = (AtomicInteger) event.data;
	handleDPIChangedScheduledTasksCount.incrementAndGet();
	getDisplay().asyncExec(() -> {
		try {
			if(!this.isDisposed()) {
				notifyListeners(SWT.ZoomChanged, event);
			}
		} finally {
			if (handleDPIChangedScheduledTasksCount.decrementAndGet() <= 0) {
				shell.WM_SIZE(0, 0);
			}
		}
	});
}

and notifyListeners will be replaced by this method.

@amartya4256
Copy link
Contributor Author

So from what you are proposing and what I think how we could do it, I devised the following order:

  1. Remove DPIZoomChangeHandler and use direct handleDPIChange calls for internal classes and use ZoomChangedEvent for Common widget.
  2. Move to Event driven model
  3. Make the event driven model asynchronous.

(The only problem I see is in the first step. If we handle ZoomChangedEvent for Common widgets like StyledText, etc, they are not scaled in the hierarchical order. I need to test if it could cause any trouble.)

@HeikoKlare
Copy link
Contributor

Sounds good, I would just try to split the first step into the adaptation of common/custom widgets and the adaptation of the native part to keep it as small as possible.

(The only problem I see is in the first step. If we handle ZoomChangedEvent for Common widgets like StyledText, etc, they are not scaled in the hierarchical order. I need to test if it could cause any trouble.)

But since everything stays synchronous, it should not matter whether you call a registry or whether you send an event.

@amartya4256 amartya4256 force-pushed the amartya4256/dpi_performance_improvement/design_improvement branch 2 times, most recently from 3bf732f to 70e8d3f Compare September 16, 2025 21:27
@amartya4256
Copy link
Contributor Author

@HeikoKlare As per our discussion, Replacing CommonWidgetZoomChangeHandler with ZoomChanged Event handler is not possible since the Common widgets need to call for the handleDPIChange for their associated widgets which is win32 specific code and we cannot call notifyListeners on these widgets without making them register to ZoomChanged event as they still use DPIZoomChangeRegistry. Hence, the following is necessary to make it work all together:

  1. Register Widget with ZoomChanged event.
  2. Implement inheritance based super.handleDPIChange for widgets to mimic DPIZoomChangeRegistry's heirarchial behaviour.
  3. For handling DPI Change for associated / children widgets, replace DPIZoomChangedRegistry.applyChange with widget.notifyListeners (This still executes synchronously).
  4. Move the CommonWidgetZoomChangeHandler methods to the Common Widgets and register them on ZoomChanged events.
  5. Remove CommonWidgetZoomChangeHandler & DPIZoomChangeRegistry/Handler.
  6. Adapt the DPI_CHANGE event trigger point in Control to use Shell.notifyListeners

For the next step, i.e. asynchrony, we will replace these notifyListeners with a Widget:sendZoomChangedEvent which will call widget.notifyListener asyncly and handle the painting upon DPI scaling completion.

@amartya4256 amartya4256 force-pushed the amartya4256/dpi_performance_improvement/design_improvement branch from 70e8d3f to 991af26 Compare September 17, 2025 13:24
Copy link
Contributor

@fedejeanne fedejeanne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks OK to me but there are still some unresolved discussions with @HeikoKlare .

Other than that, it's fine ✔️

@amartya4256 amartya4256 force-pushed the amartya4256/dpi_performance_improvement/design_improvement branch from 991af26 to a770ed0 Compare September 18, 2025 09:55
This commit improves thes design implementation for widgets in win32 by
moving away from DPIZoomChangeRegistry to an event-driven design using
ZoomChanged event and inheritance.
@amartya4256 amartya4256 force-pushed the amartya4256/dpi_performance_improvement/design_improvement branch from a770ed0 to d43db71 Compare September 18, 2025 16:01
@amartya4256 amartya4256 mentioned this pull request Sep 19, 2025
}

DPIZoomChangeRegistry.applyChange(decorations.getMenuBar(), newZoom, scalingFactor);
Menu menuBar = getMenuBar();
if(menuBar != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a space between if and (

DPIZoomChangeRegistry.applyChange(menu, newZoom, scalingFactor);
if (menus != null) {
for (Menu menu : menus) {
if(menu != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a space between if and (

Event event = new Event();
event.type = SWT.ZoomChanged;
event.widget = this;
event.detail = DPIUtil.getZoomForAutoscaleProperty(zoom);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one mustn't be the autoscale zoom. Isn't it stored as native zoom?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Design improvement for Win32 Widget scaling
4 participants