-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GUI overhaul #194
Draft
samizdatco
wants to merge
78
commits into
main
Choose a base branch
from
gui/event-loops
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
GUI overhaul #194
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- the separation isn't necessary now that there's no longer a thread boundary to be crossed - drop CanvasEvents that were just used for passing WindowSpec updates - proxies no longer need to be handed to window objects
- also dropped paint arg in renderer's Draw handler, meaning an intermediate compositing layer will no longer be created
- prevent them from being evicted by an in-flight roundtrip before being initialized on the rust side (using undefined top/left coords as an indicator)
- the initial event-loop run doesn't actually draw from the proxied events queue so misses any queued window creation events - dropping a Window object runs its destructor but the os window needs another loop run to actually close
- in pump_events mode it now uses unref() on the frame timer so the event loop won't keep the process running forever
- polling for the last ~ms increases timing accuracy significantly
- pushing it into the next pass means ~2ms when using the node event loop
- using the winit loop, this can be handled by switching to Poll mode - for the node event loop, sleep the thread rather than waiting for the next cycle (which will likely be longer than the sleep time)
- removes the need for windows to reference a preexisting GlobalApp
- UI events are delivered as they arrive, but screen updates only happen at App.fps frequency, even if no `draw` or `frame` listeners are active - Cadence no longer considers `active` state, it always runs - Cadence now uses `spin_sleep` crate for frame timing when using the node event loop - switch to using request_redraw after suspension rather that redrawing immediately - queue up a redraw when the window background color is changed, since it may show through
- the previous approach using NSView's `wantsLayer` was creating a 'layer-hosting' rather than 'layer-backed' view, disabling the AppKit redraw behavior winit expects - can now stop requesting redraw in resize handler and rely on the automatic request
- the first format suggested by the device may not be supported (e.g., `B8G8R8A8_SRGB` in #200)
- allows it to call `pre_present_notify` at the proper time between rendering and presentation - moved the dpr canvas scaling into the backend as well
- running them in the background was causing too many problems in scenarios like window-resizing where the OS expects the redraw to be synchronous
- skia has an internal restriction against using MSAA on intel GPUs (because of crashes, bad rendering quality, etc.) and refuses to generate MSAA surfaces even when the GPU claims it supports them - the sample count is now clamped by the `DirectContext:: max_surface_sample_count_for_color_type` value - there is a `ContextOptions::allow_msaa_on_new_intel` flag that can be set, but in the skia source they claim it's only reliable with D3D so it is not enabled here - this *may* make the `VulkanContext::works` test unnecessary, but keeping it until its error message stops appearing in bug reports
- when a software renderer like `llvmpipe` is the active driver `canvas.engine.renderer` will still be `GPU` in order to allow the `canvas.gpu` toggle to select between the vulkan path and the pure-CPU path
- the `activate` rust method now runs a background thread that schedules winit event-loop cycles on the main node event loop - App.launch() returns a promise that will resolve to `undefined` when the last active window is closed - the 'roundtrip' callback is now registered once at startup rather than passed with every `activate` call - most of the roundtrip packing/unpacking now lives in the `dispatch_events` helper function
- mirrors the default App.#fps - prevents potential infinite loop where the next-frame time is updated with an uninitialized `render` duration
- the mac event loop expects the redraw method not to return until the window has been updated during resizes
- use static methods on App rather than dealing with the global RefCell
- likewise embed the active keyboard modifiers at the time of the event rather than waiting until dispatch to merge the final set in - necessitated by switching to only delivering events at frame time rather than as they arrive (and accounting for the possibility of a low `App.fps` setting)
- defer event delivery until the next frame event (but then deliver all queued events)
- consolidate icon & visibility attrs and store the cursor in WindowSpec as a string - let lack of a "none" value in `CursorIcon::from_str` handle creating the None option
samizdatco
changed the title
Allow GUI windows to use the node event loop for timing
GUI overhaul
Dec 15, 2024
This reverts commit 7710418. Fixed upstream with winit 0.30.7
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Allow GUI windows to use the node event loop for timing
Adds an
eventLoop
property to the App global which can be set tonode
as well asnative
(the default). When using anative
OS event loop, the Node event loop is frozen in place while graphical windows are active. As a result functions likesetTimeout
andsetInterval
won't fire until the final window is closed.When using a
node
event loop, the app's event-loop is suspended and resumed from node, allowing for the normal use of timers within user scripts. Thenode
event loop mode is possible due to a new feature in winit that comes with quite a few caveats, so sticking withnative
mode is recommended unless you really need access to the node event loop's features.App.launch() now returns a Promise
The promise resolves when the final window is closed, so you can either
await
it or use a then() handler to run clean-up code before quitting (similar to the blocking behavior of launch() when innative
eventLoop mode).New events on the
App
globalThe
App
object is now an event emitter with on()/off/once() methods. You can add event listeners foropen
andclose
events that are emitted when a new window is created or an old one is destroyed.Event fixes
input
event (reporting new keyboard input) now distinguishes between insertions, deletion, and IME composition via itsinputType
attribute.App.fps
). Event listeners will now receive as manymousemove
/mousedown
/etc. events as were detected by the OS."none"
now correctly hides the cursor (fixing a regression in 2.0.0)moved
window events are no longer emitted during window resizes