Awesome wm/awesome and class fixups drawin impl#456
Conversation
| title = "Oops, there were errors during startup!", | ||
| text = awesome.startup_errors }) | ||
| end | ||
| naughty.notify({ preset = naughty.config.presets.critical, |
There was a problem hiding this comment.
Did you just duplicate this by accident??
There was a problem hiding this comment.
I put this in here to test notifications. I was hoping to get them working when I first started on this PR (notice a lot of the changes relate to adding cairo and xcb stuff to awesome bindings). Alas, no such luck. I'll remove this as this is a debug thing I forgot to remove.
I'm going to review this again properly and merge it in soon (tm). There's some changes here that are fairly critical (fix a lot of issues with Awesome classes that will be needed down the line. Plus it shows how to connect and use xcb)
There was a problem hiding this comment.
That would be great! I was going to base the wallpaper work off of this branch anyway!
There was a problem hiding this comment.
I'll work on cleaning this up and merging it in today.
There was a problem hiding this comment.
Ok "today" was a bit optimistic. Going to try to finish this up ASAP, but you should still base your work off this branch.
We weren't wrapping it in a table, like is expected of in Lua because Awesome does it. HOWEVER, they use lua_setuservalue. We don't have access to that, so we just put it in a table. Need to double check this does the right thing...because this doesn't seem right :(
I really need to implement these properly
By movinging it before hand, xcb can talk to xwayland and get e.g xkb information.
Also adds more safety checks for unsafely getting the group names
Even in the error case we ensure that the connection isn't closed.
Because lua doesn't have the screen, which it gets from the client or from the mouse. So I need to implement it for mouse because that's the easiest way. yay.
The way it's done is crazy, but basically mouse has a reference to the screen table and then if screen global gets a screen instance we just return it. Again, it's really crazy
I was saving it on the instance of the class instead of the class itself, which makes sense in retrospect
You should set it on the class instead
Took way too long because the C code is inscrutable
0eaafcb to
bdffbbd
Compare
Had to update dummy-rustwlc -_-
67659b2 to
dc5a560
Compare
This is to get around issues with testing...also it's technically correct, as we don't have hard dependency on xwayland _quite_ yet
|
Currently we are doing the objects allocation wrong here. We are allocating the tables weirdly, and we need to be 1-1 on what Awesome does. Once that is setup properly, writing the APIs will be easy enough that it can be done in parallel. cc @psychon We talked a bit about this on the gitter channel, but I know it's hard to read this Rust when you're not familiar with it. Any quick run-down on how the objects (e.g like a |
Well... it's a userdata with some object-specific fields, some of them read-only. The general "stuff" is:
Each object has a class, e.g. a client belongs to the
I'll try to give your rust code a close look later. |
| pub surface: Option<ImageSurface>, | ||
| geo: Geometry, | ||
| refreshed: bool, | ||
| // TODO Refresh callback |
There was a problem hiding this comment.
You are using an ImageSurface which allocates its own memory to draw to; awesome uses a XcbSurface drawing to the pixmap. Thus, you don't need a pixmap member here, it's just the "target" for drawing in awesome.
The refresh callback is just an internal implementation detail. For drawins it copies from the drawable's pixmap to the screen and for titlebars it does basically the same. However, for your case it should be enough to just always copy the contents of the surface to the screen on each frame and basically ignore the refresh function that Lua calls (it is always valid to use the contents of the surface, the refresh callback from Lua is just a "I changed something"-signal to force a repaint; this can of course be optimized later).
Edit: Oh, okay, I forgot about the refreshed member. Okay, refresh can just set that boolean and you only draw if it is true...
There was a problem hiding this comment.
Thanks, I had a feeling I didn't need a pixmap but I hadn't looked into whether or not I needed it.
Ok so I don't even really need to add it as a field, I can just have a refresh function that checks the bool and only draws if it's true then. That will simplify this.
| use super::dummy; | ||
| builder.method("connect_signal".into(), lua.create_function(dummy))? | ||
| .method("__call".into(), lua.create_function(dummy_create)) | ||
| .method("__call".into(), lua.create_function(|lua, _: Value| Drawin::new(lua))) |
There was a problem hiding this comment.
Oh and the global (e.g. drawin) when called get a table of properties to be applied, for example visible = true (but the table can also contains keys that the C code does not understand and thus ignores). This code looks like you explicitly ignore these extra arguments.
There was a problem hiding this comment.
Nice catch, I'll fix that when I fix the object creation (so I can throw those unknown keys into data)
There was a problem hiding this comment.
I don't think awesome stores unknown keys into data, it just really completely ignores them.
This seems to be done in luaA_class_new in common/luaclass.c: All strings for which it finds a lua_class_property_t are handled, all others are just silently ignored.
(This is like this mostly for "historic reasons", I guess; I don't know if it makes sense or not)
| }).unwrap_or_else(|err| { | ||
| warn!("err: {:#?}", err); | ||
| Some("pc+us+inet(evdev)".into()) | ||
| }).unwrap()) |
There was a problem hiding this comment.
I liked your previous "just return static fake data" version of this more. :-)
On a more serious note, I would expect a wayland compositor to already have the required data here somewhere. From a quick look at wlroots, this data seems to be in struct roots_keyboard_config (which is part of the example compositor, so perhaps wlroots requires the compositor to handle this itself?).
There was a problem hiding this comment.
In wlc (the current compositor framework Way Cooler uses) that information is not exposed (or at least, not anywhere I can see). It, along with xwayland stuff, is all handled internally.
When we switch to wlroots though that will definitely be what we do. Also yes you're correct we have to handle it ourselves--that's the main benefit of wlroots actually is that we have to manage more stuff (compared to wlc). This increases the complexity of the compositor but also gives enough control that we can do stuff like this.
I'm going to keep this really bad version, since it actually gets the required info necessary for the user. When we switch wlroots though it will definitely change :)
| /// This actually does nothing, since this is Wayland. | ||
| fn register_xproperty<'lua>(_: &'lua Lua, _: Value<'lua>) -> rlua::Result<()> { | ||
| warn!("register_xproperty not supported"); | ||
| fn register_xproperty<'lua>(lua: &'lua Lua, (name, v_type): (String, String)) -> rlua::Result<()> { |
There was a problem hiding this comment.
I think I would implement this purely in Lua (somehow). In awesome, awesome can be restarted while the X11 server continues running, so there it makes sense to save things in the X11 server. For way-cooler, a restart surely loses all the state (right?), so emulating xproperties in Lua is okay.
What do you think?
(No, I don't know how to actually do this; it's just a thought.)
There was a problem hiding this comment.
We may still need to implement this actually, because we will be relying on xwayland a lot and, AFAIK, the xwayland server lets you register xproperties to the clients still.
If the main use case is to store state in case of a restart though, that means we may need to do some hoops to achieve this...
You're right in that if way-cooler was to restart (e.g the process died) then we would lose all state because Way Cooler is not only the window manager but also the display server. If the use case is primarily recovery from the process dying (e.g from an error) then we would need to achieve this via some other way.
One thing we could do is run Lua in a totally separate process and communicate between Way Cooler and Lua via IPC. Though that would obviously be:
- Slower
- Way more complicated
That would achieve the same thing Awesome currently does with X11 (since they are separate processes there) but it would mean more work.
Depending on the use case, this could drastically affect the design. But it shouldn't affect implementing the interface, as I'll be moving things around when we move to wlroots anyways. I'll be thinking about this though, thank you.
There was a problem hiding this comment.
Well, the "global state" (xproperties on root) is not all that interesting, I think. And xproperties on individual client objects will still be lost since when the display server dies, all clients die with it.
Yes, this xproperty API is from a time when awesome was still restarting whenever the screen configuration changed. Ever since awesome stopped doing that, I haven't seen much use of this API.
| // TODO | ||
| Some(lua.create_function(screen_new)), | ||
| Some(lua.create_function(get_visible)), | ||
| Some(lua.create_function(set_visible)))) |
There was a problem hiding this comment.
Huh? Screens don't have a visible property and Lua cannot (that easily) create screens.
There was a problem hiding this comment.
Whoops, looks like an oversight. I'll remove those.
|
Thanks for the detailed writeup! I'm going to work on this PR more and get it to be compliant ASAP. I'm mostly trying to focus on wlroots, since that's going to necessitate mostly starting from scratch on the compositor, but this is really important to enable both me and others to work on whatever part of the Awesome API that seems easiest / most interesting to work on.
Ahhh, ok that was the missing piece in my information. Previously I tried to store these things in the object itself but ran into a lot of issues which prompted the discussion in this rlua issue thread. Here's the relevant takeaway from the thread:
|
It's not 1-1 with Awesome, but from a user's perspective as long as they don't do weird raw setting/getting on the data I give them it should be all good.
Doing this so it can still work on master. If it's uncommented, then you need to fix layoutboxes since it's used in the default rc.lua
|
Ok I think I fixed all the issues I had with this PR. Still some rough edges around the core object stuff, but nothing blocking working on the other issues. Gonna give this one more look through and then merge it later today. |
This has some crucial changes needed for AwesomeWM compatibility. There are also some additions for drawin, drawable, and others etc. but they are incomplete. I'm merging them anyways so I don't have to duplicate the effort later but those APIs should still be considered incomplete.
With these changes the
rc.luano longer properly runs (it fails trying to access a layoutbox property). I will attempt to fix that however because I want the masterrc.luaalways to be usable for testing purposes.