Reviewed the code before the ship!
noting much to report, i’ll just put the new lockscreen again
A lot of big changes!
these 10 hours of coding felt like a constant rabbit hole, but i finally fixed all the things i found TuT.
First of all, i made some new widgets: namely, a text input for the password that reserves space for the “login failed” failure text, an uptime widget and widget that fetches the default network interface.
While making an example lock screen using these new widgets, i noticed that taking a screenshot was just a huge pain; One had to go do gpu texture copying magic and it was just A Bad Time in general. So, i decided to bake that functionality into lockrs itself, so now there’s a screenshot feature (enabled by default) which makes it able to save screenshots.
But while implementing the screenshot feature, i noticed that there were some inconsistencies in the multiple output logic and in the buffer scaling logic, so i fixed those (this took surprisingly long :p).
After implementing that, i went to take that screenshot, and noticed that the UI would freeze for a bit while the disk I/O of saving the image was running. This was quite annoying, so i also decided to make a whole ass worker thread that handles password checking (which also used to hang the UI thread, albeit for a short time) and to save the screenshot.
Anyways, after this journey of a few days of coding, here’s the example screenshot, finally:
P.S.: while trying to put an image here, firefox crashed and i had to rewrite this whole thing… to anyone seeing this, save your devlogs somewhere before adding pics :p
Well, im at it again with this project. I took quite a long break to make another project, and now have had the time to come back to this. I’ve finally written some in-depth docs, and will review them later today with a fresh mind to be sure that they’re as right as possible.
I also fixed a design flaw, but im not very sure if how i did it really fixed it. Before, this is the old way it’s doing it:
app.ui(|_, ui| {
// put stuff inside some ui levels
egui::CentralPanel::default()
.frame(egui::Frame::NONE)
.show(ui, |ui| {
// maybe make new ui levels
// inside the levels, return TryExit
TryExit::Force
})
.inner.inner.inner //as many .inner as ui levels
// TryExit is in, because you need to return the inner TryExit
})
this felt extremely clunky. So, i solved it like this:
// mutable reference to a TryExit
app.ui(|_, ui, exit: &mut TryExit| {
// as many levels as you want
egui::CentralPanel::default()
.frame(egui::Frame::NONE)
.show(ui, |ui| {
// instead of returning it, mutate the passed-in reference
*exit = TryExit::Force;
}); // no need to return anything, so no .inner
})
this feels a bit better, but idrk still. For the time being, the API will be the latter.
Anyways, have a look at the new docs:
Well, this was a disaster. To the people who saw my last devlog, i said that i was going to try to fix a problem that i encountered by using resizing and movement animations simultaneously.
I spent an egregious amount of time researching how i could force smithay to render the window stretched in such a way that it would cancel out any size errors, but it turns out that the method i used just… did nothing? i dont really know what happened, but i made a quick and dirty fix for now by making the movement animation wait a couple of animation ticks before starting, and it has worked decently so far.
I think i’ll get to work on the privileged section’s movement and swaps and whatnot now.
Below is an example where you can see that the edge isn’t freaking out like before anymore:
I’ve been at work to make animations, and it turned out decently. The only real problem i have with the current implementation is that when a window is subject to both a resize animation and a move animation, the far edge of the window in relation to the one that’s moving will bleed into the next cell a bit, so i need to fix that.
Other than that, it’s smooth sailing; now i only need to fix that last problem and probably refactor the animation code because it’s a complete mess.
Here’s a video of the animations working:
I was planning on just abstracting away some parts of functions in other functions for this devlog, so that i could complete the window expansion and movement logic. Since i had spent barely half an hour doing that i thought this devlog would have been too short, so, i also decided to start making movement and resizing animations; but little did i know that i was, all of me, deceived.
As i was thinking at yesterday’s code, i found some inconsistencies in my logic, i ended up also fixing a bunch of bugs that completely escaped me while writing the code, and i ended up needing to fix those…
The first bug i found regarded the movement and expansion of windows: what should a window do if in the way it wants to move there are two windows, the first that can move out of the way and the other can’t? Up until now, the window that had to move (or expand) would not have performed the action because of the 2nd window, but the first one would have moved regardless. I fixed it so that if any of the obstructing windows cannot move, none will.
While fixing the first bug, i stumbled upon a second one; in my tiredness from late-night coding, i had somehow managed to forget to update the available cells when a window expands… Yeah that was dumb TuT.
Now again, while fixing the second bug, i found a third! This one was perhaps even dumber, because i had forgotten to update the cells a new window occupies when it expands. Again, quite dumb, but now it works at least…
I managed to add a few things, going insane in the meanwhile.
First of all, i reorganized the files of the project in some folders, because more folders are (almost) always good.
Second, i discovered that a decent algorithm i had made to find which window was under the pointer, which first checked the section (top or bottom), then row and column (which would make a small amount of checks), can’t work while i don’t lock in my layout! this is because i can’t get a certain window geometry unless i do a linear search over every window, which is a complete waste of time, because at that point, it’s faster to just make a linear search over all windows and check if each is under the pointer. So, until i figure out the spacing and in general the fancy stuff in the layout, i won’t be able to use my algorithm.
Third, i went absolutely insane trying to implement multi-cell windows on the map. like. i think i remade the algorithm close to 10 times before landing on something i like. in the meanwhile, i also added moving windows, simply because if you try to extend a window into already occupied cells, the layout manager will try to move all windows in the row(s) or column(s) out of the way to make space for the expanded window. I am quite happy with it now, even if it can only be expanded to the right for now because i want to split up some huge functions into smaller functions.
Anyways, here’s a demo; it spawn three terminals, moves the third one under the first one, extends the one that just moved once to the right, and then moves the first and second window downwards and back, moving the extended window in the meantime.
Note: for some reason, the terminal that gets extended doesn’t realize it was extended until i type something, hence it looks like a very very very bad cut. I swear it isn’t, you can look at the code if you don’t believe me TuT
I managed to do a bunch of stuff, in no particular order:
weston-terminal wouldn’t lose its window decorations even if it seemed like i was doing everything right for a good 45 minutes. Only after that amount of time, i decided that it would have been wise to try another terminal, and would you believe it! alacritty removed its decorations flawlessly! turns out that weston-terminal just… doesn’t respect the decoration config??? anyways, i’m now using alacritty and kitty because they respect the decoration config and have slightly different colors by default.)Anyways, have a demo video; you can see alacritty and kitty being alternated because the former has a grey-ish background, and the latter has a black background:
I got winit to work, and it was surprisingly easier than i thought it would be. Also, i fixed a bug where columns and rows were swapped in the bottom grid, oops.
Anyways, it works! and my layout manager does too! Well, at least partially, because the top strip isn’t resizing the windows like i want it to, but that’s something i’ll work on in the future.
Well, this is a huge project. For now, i’ve worked actually learning how a compositor is made, and how to do tiling. I should have the bases for a layout manager and an app state manager, but, knowing how these things go, they’re likely both broken in some way.
For now, the tiling is split in two sections: the top one, is privileged and cannot be attacked, meanwhile the bottom section is a grid where the windows will be hittable boats by opponents
Anyways, i’ll try to make the backend trait and to implement the winit backend to get a display out.
After taking a small break, i finally finished this project. I decided to turn it into a library instead of a really customizable lockscreen, because what would be the purpose in making something that could very well work in any number of ways and then limiting it to a few widgets? I’m quite satisfied with how it turned out, even if there are a few rough spots. Also, i decided to license it under MIT or Apache 2.0, as per convention for rust libraries.
In the end, i’ll be definitely using lockrs, and i hope some other people will too.
I managed to add PAM authentication. I also tried to add support for shaders and in general gpu work, and discovering i bit off way more than i can chew, i just decided not to.
So, i tried to add a background, but i stumbled upon an obstacle which sent me diving into egui’s source code, because it kept claiming that it couldn’t load images with side bigger than 2048px; turns out this is only a limitation of the WebGPU API, that, as the name suggests, runs on browsers, not on desktops. Anyways, after a lot of fiddling with egui’s components, i managed to make it use images with sides up to 8000px.
Now i’ll probably customize the bar a little, and maybe make a few egui widgets for it.
After wrecking my mind unnecessarily over how to handle pointer events for a ridiculous amount of time, I finally got something that somehow works; now i also have a working text input! It just prints the input to the terminal for now, but I’ll be messing with PAM a bit to do authentication now. wish me luck!
I finally got the keyboard to work! for now, it just exits as soon as a key is pressed, but i’m working on implementing full functionality. also, now the code is much much cleaner, properly divided in functions instead of being all chucked into main. I don’t really have a way to display this with a screenshot, so i’ll just reuse an old one unfortunately :p
Well, i managed to render to the lock screen with egui instead of using
the raw buffer; for now, it’s still a mess of spaghetti code that barely
works and will turn into a footgun very quickly if i don’t get
working on the lower level part of it instead of throwing stuff at the
wall and seeing if it sticks. The next step is tidying the code up
instead of throwing everything into main, so that i can get some
customization going. Also, i should probably add the authentication part
of the lock screen instead of having it unlock after a few seconds.
I finished a first proof of concept for wl-lock; right now, it locks the user out for two seconds while displaying a mauve screen.
For now, it’s still fully cpu rendered, but i plan on adding gpu-accelerated background blur and general effects.
The next step is hooking egui into it!