awesomeWM / awesome

awesome window manager
https://awesomewm.org/
GNU General Public License v2.0
6.33k stars 596 forks source link

Porting AwesomeWM On macOS #3446

Open danymat opened 2 years ago

danymat commented 2 years ago

Hello everyone,

I'm interested in porting AwesomeWM on MacOS. I just saw an old issue (#2453) that was talking about that, and the difficulties of it. I currently use yabai in my workspace (open source Mac OS tiling manager) and tried out awesome on linux.

this is welcome and given we will soon already support 2 backends because of wayland, a third one that passes the tests is very much possible.

What's the current state of this ?

Thanks for your wonderful work, be sure that I would love to contribute to it by extending this beloved application on MacOs platforms !

ezz666 commented 2 years ago

You can search through the issues. Apparently wayland port status is wontfix for now. The last update described in this comment .

Elv13 commented 2 years ago

We already have 2 backends. The X11 one and the one used for the images in the documentation. The size of the core API is pretty small. So it isn't that much work to write a backend. However, that backend needs to use a GLib main loop. Other than that, you implement those ~300 functions/methods/properties and it's pretty much good to go. The example images backend is only 1312 lines (of Lua) long and is "complete". Obviously it does nothing and is only enough to render whatever scene is being thrown at it. A real backend would need to interact with the macOS accessibility APIs to move the windows around and add the bars/popups. For the bar/popups, there is already a Cairo backend for Quartz, so that should be pretty simple (beside all the code to lock the backs into place)

That being said, that's quite a lot of work. I would also advise not to try to extend/re-use the current X11 C core. That didn't go very well the last time it was tried.

heavyrain266 commented 2 years ago

Quartz isn't X11 based for years (there was HerbstluftWM version for macOS) but the problem is that, it's not really possible to "port" Awesome as Quartz extension in style of Yabai. Yabai itself is really advanced and slowly dying becose of being reversed engineered Quartz, which requires a lot of work and makes some issues on M1 macs and newer versions of macOS itself. Porting Awesome wouldn't be "legal" as in would require reverse engineering Quartz and porting whole backend. Eventually being completely rewritten in Swift (like Amethyst - XMonad style WM) and highly limited since would need bindings for libs used in backend or being "limited" by web based widgets from übersicht..

Elv13 commented 2 years ago

Quartz isn't X11 based for years (there was HerbstluftWM version for macOS)

Awesome 3.0 - 3.4 are known to work fine on macOS. I haven't seen any screenshot of newer versions, but I assume they also work. Using X11 WMs on macOS has some limitations like only being able to manage X11 window, but it "works". This isn't what this issue is about.

Porting Awesome wouldn't be "legal" as in would require reverse engineering

Isn't there some accessibility APIs which are disabled by default, but officially supported?

Eventually being completely rewritten in Swift

I am pretty sure Objective C/C++ could be used the last time I looked at it. I know this isn't the cool kids way of coding, but since accessing glib is pretty much impossible to avoid, C-like languages are easier to use than binding Swift?

As for the backend "rewrite", it isn't that dramatic. There is a Quartz backend for Cairo and AwesomeWM backend API isn't that large. We already have 2 complete backend implementations. Waycooler also came pretty close at some point (an earlier rewrite, not the final one, which shared some code with the X11 backend). So creating new backends is definitively possible. It has to:

The screen, mousegrabber, mouse, systray, selection and root core APIs can be initially ignored and most things will work fine-ish. The tag API can port the SVG backend Lua implementation rather than have it in the macOS core. To have tag in the core, it would need to somehow take control of macOS Mission Control system, which I don't think is possible.

koekeishiya commented 2 years ago

Yabai itself is really advanced and slowly dying becose of being reversed engineered Quartz, which requires a lot of work and makes some issues on M1 macs and newer versions of macOS itself.

I don't agree with this statement; I just have not bought an M1 mac yet.

Elv13 commented 2 years ago

@koekeishiya Hi, while you are here and you are the world expert on this topic, can you shed some light on the dark corners of such a "port"?

Assuming some magic IPCs appears for skhd and some contributors has infinite time. Do you think yabai is a good base if an IPC is bolted on top of it to talk to an imaginary AwesomeWM process? Or should AwesomeWM get a native/dedicated/built_in WM core for macOS? In the end, >=80% of AwesomeWM are the libraries and high level APIs to write the modules/business_logic. The core doesn't do much beside moving windows around and listening for specific events.

Can you elaborate on the magic to coerce macOS into not showing the menubar and add arbitrary unmovable bars/boxes on the screen? How hackable is mission control?

koekeishiya commented 2 years ago

Do you think yabai is a good base if an IPC is bolted on top of it to talk to an imaginary AwesomeWM process? Or should AwesomeWM get a native/dedicated/built_in WM core for macOS? In the end, >=80% of AwesomeWM are the libraries and high level APIs to write the modules/business_logic. The core doesn't do much beside moving windows around and listening for specific events.

It has been a long time since I last used AwesomeWM, so I am not very informed regarding its architecture. One key thing about all window management utility on macOS is that they have to use the accessibility API that macOS provides, to move and resize windows. This accessibility API also happens to be single threaded (in late Big Sur and Monterey I have seen an undocumented function that supposedly spawns a second thread to handle AX requests), and it has a global mutex that is system-wide.

Because of this I'd be cautious with adding a lot of layers between the client/caller and the actual core. Thus, I don't necessarily think that it is smart to reuse yabai as the core with an IPC. I do however think that a dedicated macOS backend (based on how yabai works) inside AwesomeWM could work quite well.

Firstly, macOS is heavily event-based, and everything that you need to receive/react to is going to happen through some sort of callback. Some of these can be registered system-wide, and other must be subscribed to on a per entity basis (e.g for every application, for every window, etc.). These callbacks run through what Apple calls a Run Loop.

You can specify which Run Loop an event-handler will run in when subscribing for these events, but I found it easier to simply create my own event loop thread that I manage, which reads from a non-blocking queue. All events that are observed from macOS are placed into this queue (regardless of which Run Loop/thread the observer was assigned to).

Since we are unable to fully replace the macOS desktop environment, we have to do some extra steps during setup to detect applications that are already launched when our window manager starts, as well as monitor process creation and termination. I use the older (but still functioning) Carbon Process Manager for this to achieve the most correct result. I had some issues using the "modern" NSWorkspace API family, in which information was missing.

I was initially going to write more, but as I am writing this I realize that I would have to write half a book to really cover the interesting parts. I suppose people interested in doing such a backend implementation would be better of just looking at the yabai codebase (MIT Licensed) and just ask me questions if something seems really wacky or unclear.

I suppose the key parts to look at would be the following files:

Process Management: https://github.com/koekeishiya/yabai/blob/the-future/src/process_manager.c Window Management: https://github.com/koekeishiya/yabai/blob/the-future/src/window_manager.c Some System Events: https://github.com/koekeishiya/yabai/blob/the-future/src/workspace.m Application/Window Events: https://github.com/koekeishiya/yabai/blob/the-future/src/application.c and the actual event handling: https://github.com/koekeishiya/yabai/blob/the-future/src/event.c

Can you elaborate on the magic to coerce macOS into not showing the menubar and add arbitrary unmovable bars/boxes on the screen? How hackable is mission control?

So the macOS menubar is just hidden; this is a setting in System Preference > General > Automatically hide and show the menubar. I think there are some undocumented settings to adjust the time required for it to resurface upon mouse hover, but I haven't tested it.

Custom bars or UI elements that you see are mostly just regular Cocoa (or you can use the undocumented C APIs) windows that are drawn without decorations and made non-resizable. You can then use whatever graphics API you want, whether it be OpenGL or Metal, or just simply use CoreGraphics.

As for Mission Control.. it is actually a part of the Dock.app binary. So the entire Mission Control UI, spaces (+ gestures), expose, application swithcher (cmd + tab), and even the wallpaper is all Dock.app. To change or customize any of this, you'd need to reverse engineer the internals to locate datastructures and the active instances, inject code that modifies these in the ways that you want.

This I'll admit is more work than most people can be bothered to do. I'm only familiar with TotalSpaces, and yabai, that actually does this. Not to mention that to inject code the user will have to disable rootless (System Integrity Protection) on their macOS system. So, not very customizable, but hackable given enough effort.

I'll leave it at this for now as a general answer. There is a whole bunch of things to elaborate on here, but I am having a hard time writing it down in a coherent way when we are not looking into a particular section or more specific questions.

--

Yabai already has a pretty good CLI for integrating third party tools, and while I probably would not use it as a core, it could be used to experiment and test whether the feature-set that it provides is something that would be feasible to try and build into a backend in AwesomeWM.

If someone is interested in specific parts of the implementation/problem statement, I could probably be more helpful.