When filling in some missing part of a window (typically happens during
interactive window resize) we now use the ColorRole::Background from
the system theme palette instead of expecting the clients to send us
the same information when creating windows.
WindowServer now tracks whether windows are occluded (meaning that
they are completely covered by one or more opaque windows sitting above
them.) This state is communicated to the windows via WindowStateChanged
messages, which then allow GWindow to mark its backing store volatile.
This reduces the effective memory impact of windows that are not at all
visible to the user. Very cool. :^)
Instead of implementing menu applets as their own thing, they are now
WSWindows of WSWindowType::MenuApplet.
This makes it much easier to work with them on the client side, since
you can just create a GWindow with the right type and you're in the
menubar doing applet stuff :^)
We now show a quick window outline animation when going in/out of
minimized state. It's a simple 10 frame animation at 60fps, just to
give a visual cue of what's happening with the window.
The Taskbar sends over the corresponding button rect for each window
to the WindowServer using a new WM_SetWindowTaskbarRect message.
Note that when unminimizing, we still *show* the window right away,
and don't hold off until the animation has finished. This avoids
making the desktop feel slow/sluggish. :^)
This patch introduces code generation for the WindowServer IPC with
its clients. The client/server endpoints are defined by the two .ipc
files in Servers/WindowServer/: WindowServer.ipc and WindowClient.ipc
It now becomes significantly easier to add features and capabilities
to WindowServer since you don't have to know nearly as much about all
the intricate paths that IPC messages take between LibGUI and WSWindow.
The new system also uses significantly less IPC bandwidth since we're
now doing packed serialization instead of passing fixed-sized structs
of ~600 bytes for each message.
Some repaint coalescing optimizations are lost in this conversion and
we'll need to look at how to implement those in the new world.
The old CoreIPC::Client::Connection and CoreIPC::Server::Connection
classes are removed by this patch and replaced by use of ConnectionNG,
which will be renamed eventually.
Goodbye, old WindowServer IPC. You served us well :^)
The Launcher's functionality has been replaced by the app shortcuts in
the system menu.
There were various window management hacks to ensure that the launcher
stayed below all other windows while also being movable, etc.
Okay, I've spent a whole day on this now, and it finally kinda works!
With this patch, CObject and all of its derived classes are reference
counted instead of tree-owned.
The previous, Qt-like model was nice and familiar, but ultimately also
outdated and difficult to reason about.
CObject-derived types should now be stored in RefPtr/NonnullRefPtr and
each class can be constructed using the forwarding construct() helper:
auto widget = GWidget::construct(parent_widget);
Note that construct() simply forwards all arguments to an existing
constructor. It is inserted into each class by the C_OBJECT macro,
see CObject.h to understand how that works.
CObject::delete_later() disappears in this patch, as there is no longer
a single logical owner of a CObject.
You can now call GWindow::set_fullscreen(bool) and it will go in or out
of fullscreen mode.
WindowServer will also remember the previous window rect when switching
to fullscreen, and restore it when switching back. :^)
This was a workaround to be able to build on case-insensitive file
systems where it might get confused about <string.h> vs <String.h>.
Let's just not support building that way, so String.h can have an
objectively nicer name. :^)
Now that we can set icons directly "by bitmap", there's no need for passing
around the icon paths anymore, so get rid of all the IPC and API related
to that. :^)
Now that we support more than 2 clients per shared buffer, we can use them
for window icons. I didn't do that previously since it would have made the
Taskbar process unable to access the icons.
This opens up some nice possibilities for programmatically generated icons.
This macro goes at the top of every CObject-derived class like so:
class SomeClass : public CObject {
C_OBJECT(SomeClass)
public:
...
At the moment, all it does is create an override for the class_name() getter
but in the future this will be used to automatically insert member functions
into these classes.
Instead of LibGUI and WindowServer building their own copies of the drawing
and graphics code, let's it in a separate LibDraw library.
This avoids building the code twice, and will encourage better separation
of concerns. :^)
Taskbar now simply asks the WindowServer to popup a window menu when right
clicking on a taskbar button.
This patch also implements the "close" menu item, and furthermore makes the
window menu show up when you left-click a window's titlebar icon. :^)
Also run it across the whole tree to get everything using the One True Style.
We don't yet run this in an automated fashion as it's a little slow, but
there is a snippet to do so in makeall.sh.
Fullscreen windows are rendered alone and above everything else when they
are active, and as part of the regular window stack order when something
else is active.
Currently windows cannot be made fullscreen after-the-fact, but must have
the fullscreen flag included in their CreateWindow message.
It should not possible to interact with the menu, taskbar or window frame
while the active window is fullscreened. :^)
This patch moves to sending up to 32 rects at a time when coordinating the
painting between WindowServer and its clients. Rects are also merged into
a minimal DisjointRectSet on the server side before painting.
Interactive resize looks a lot better after this change, since we can
usually do all the repainting needed in one go.
This was pretty straightforward thanks to the work I did separating out
LibCore from LibGUI already. :^)
- WSMessageLoop now inherits from CEventLoop.
- WSMessage now inherits from CEvent.
- WSMessageReceiver goes away.
Now there is only one event loop in Serenity. Very nice!
Only process paint and resize events on the GUI client side if those events
have the latest up-to-date window size. This drastically reduces async
overdraw during interactive resize.
When resizing a window, we often end up having to paint some part of it
without coverage in the current backing store. This patch makes those cases
look nicer by having a fallback background color for each window, passed
along with the CreateWindow client message.
The window is simply ignored in the painting and hit testing traversal
when in minimized state, same as we do for invisible windows.
The WM_SetActiveWindow message (sent by Taskbar) brings it back into the
non-minimized state. :^)
The window frame is an object that contains a window, its title bar and
window border. This way WSWindowManager doesn't have to know about all the
different types of window borders, titlebar rects, etc.
I originally thought I would do this inside WindowServer, but let's try to
make it as a standalone app that communicates with WindowServer instead.
That will allow us to use LibGUI. :^)
When a mouse button is pressed inside a window, put that window into an
automatic mouse tracking state where all mouse events are sent to that
window until all mouse buttons are released.
This might feel even better if it only cared about the mouse buttons you
actually pressed while *inside* the windows to get released, I don't know.
I'll have to use it for a while and see how it's like.