treeform / windy

Windowing library for Nim using OS native APIs.
MIT License
117 stars 16 forks source link

Make Windy Modular #92

Closed Patitotective closed 2 years ago

Patitotective commented 2 years ago

It would be really cool if Windy was modular so you only imported the things you really use.

import windy/clipboard
Patitotective commented 2 years ago

It would also help to make the documentation shorter and easier to read.

guzba commented 2 years ago

I have made a couple of attempts at this and concluded it is actually a deceivingly complex request and not something I'm going to do in in the near future.

For context, the current Windy is not done. I've only done Win32 and macOS first-pass so far, planning to look at Linux next (current Linux was contributed which is great but has shortcomings I need to address). Given I haven't even done all 3 platforms, taking on something that adds a lot of complication is sadly not a good idea at this point.

Some reasoning in addition to that:

Well, on Windows, setClipboard requires an HWND (window handle). So either the proc signature cannot match across platforms (needs that HWND paramter on Windows), or windy/clipboard needs to know about eg windy/windows in order to have a little helper internal HWND. And that internal helper HWND brings further concerns. It cannot be created at global scope due to potentially using windy in a DLL (DLLs must not call out to other DLLs in DllMain which is when the global scope code is run, so calling out to the Windows DLLs to create a window is a no-go). So, either windy needs a global init proc that must be called first, or windy can do a if not initialized: init() internally like it does now,. Then either the explicit init call or the call that triggers the check + initialization (like setClipboard) must be called on the main thread. This is because windows event loops are tied to the thread that created it on Windows. There is even more to this but that's enough for now.

So this big long blob above that probably didn't make sense is just the tip of the iceberg, literally just for setClipboard. When you start adding in notifications, windowing, platform http, tray icon, it gets really really tricky. The platforms themselves are made as a monolithic API all focused around a single event loop, so breaking bits of it off just ends up falling apart when at the bottom of it all, only one bit of code can be in control of the platform event loop.

I could maybe create the needed little helper window just for clipboard and have other ones for each other module, but it does not seem great to have like 5 hidden windows just to enable the use of import windy/clipboard instead of import windy. And I am very sure there are further painful realizations that would stop this approach too.

In the end, Windy isn't mature yet so while the suggestion of refactoring it into modules is reasonable, in reality it is complicated and quite for ahead of where the library is today. Perhaps someday, because the idea itself is good, but for now I am going to close this.

Patitotective commented 2 years ago

Thanks for the answer. I agree and hope Windy matures quickly, it is such a useful library :heart:.