Skip to content
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

Improve event loop on Linux/Gtk #635

Open
wusyong opened this issue Nov 30, 2022 · 1 comment
Open

Improve event loop on Linux/Gtk #635

wusyong opened this issue Nov 30, 2022 · 1 comment
Labels
platform: Linux priority: low Nice to have status: needs triage This issue or pull request needs to be investigated type: feature request

Comments

@wusyong
Copy link
Member

wusyong commented Nov 30, 2022

The reason of current implementation looks like this is because we have to comply the restriction of Gtk and the design of tao/winit itself: Both of them want to occupy the main thread. There are some improvements we can choose, but they all have different kind of drawbacks. In this issue, I want to list some alternatives I want to take before.

Add event toggle method

The most common bottlenecks usually comes from too many events sent at the same time like cursor moving or window resizing. With the closure of the event loop needs to run grows too big, it might create noticeable delay when users interact (like moving cursor and found the animation is slightly stuttering).

We can add some toggle method when creating event loop and windows like device event filter. This could reduce the amount of event being sent on specific cases.

The drawback might be how granular should it be, and it might become more complicated when creating these windows.

Adopt Glib's channel and ignore control flow

I used to implement glib's channel before adding control flow. It works better with current implementation and should run smoother when dealing with events. But it cannot satisfy the requirement of ControlFlow::Wait, Poll, and WaitUntil. So I refactor to what we have nowadays. The channel couldn't detect when the normal events and draw events channel are empty.

If we choose to revert it back, that means ControlFlow::Wait, Poll, and WaitUntil will be ignored. @amrbashir suggested maybe this can be an extended trait like EventLoopExtUnix::run_with_glib_channel as an alternative for those who don't care control flows.

Create a Gtk thread instead

Despite Gtk usually tells you it must be used on the main thread, it's actually possible to run in other threads. It only cares which thread calls gtk::init first, and that thread will be the main context for Gtk. If we can just create a thread, call gtk::init there, and move all Gtk logics to the thread, tao and Gtk won't block each other. This is the best case for performance and bug free we can get.

The huge drawback is this is almost a total rewrite. This also means main thread cannot call any Gtk related functions, otherwise the program will simply crash. As a workaround, users, including us, can call idel_add when you want to use Gtk related crates like rfd or libappindicator. But this creates a really bad development experience as all calls must move to the closure. There will be a lot of channel passing and mutex sharing if you want to keep some states or stuff in main thread.

@wusyong wusyong added platform: Linux type: feature request status: needs triage This issue or pull request needs to be investigated priority: low Nice to have labels Nov 30, 2022
@wusyong
Copy link
Member Author

wusyong commented Dec 7, 2022

I tried to refactor with idle_add today.
It becomes pretty restrictive and cannot block while waiting.
I'll see if we can use gtk::events_pending next time to reduce event channeling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: Linux priority: low Nice to have status: needs triage This issue or pull request needs to be investigated type: feature request
Projects
Status: 📬Proposal
Development

No branches or pull requests

1 participant