Color themes are loaded from .ini files in /res/themes/
The theme can be switched from the "Themes" section in the system menu.
The basic mechanism is that WindowServer broadcasts a SharedBuffer with
all of the color values of the current theme. Clients receive this with
the response to their initial WindowServer::Greet handshake.
When the theme is changed, WindowServer tells everyone by sending out
an UpdateSystemTheme message with a new SharedBuffer to use.
This does feel somewhat bloated somehow, but I'm sure we can iterate on
it over time and improve things.
To get one of the theme colors, use the Color(SystemColor) constructor:
painter.fill_rect(rect, SystemColor::HoverHighlight);
Some things don't work 100% right without a reboot. Specifically, when
constructing a GWidget, it will set its own background and foreground
colors based on the current SystemColor::Window and SystemColor::Text.
The widget is then stuck with these values, and they don't update on
system theme change, only on app restart.
All in all though, this is pretty cool. Merry Christmas! :^)
Allow everything to be built from the top level directory with just
'make', cleaned with 'make clean', and installed with 'make
install'. Also support these in any particular subdirectory.
Specifying 'make VERBOSE=1' will print each ld/g++/etc. command as
it runs.
Kernel and early host tools (IPCCompiler, etc.) are built as
object.host.o so that they don't conflict with other things built
with the cross-compiler.
4KB gets pretty mmap/munmap heavy when downloading larger files,
so bump this a bit to reduce time spent in memory allocation.
This can be improved in various ways, but I'm not sure what the
best way forward is at the moment.
This patch exposes some fields about purgeable memory regions.
We now also show total purgeable volatile and non-volatile memory in
the big process table.
Using int was a mistake. This patch changes String, StringImpl,
StringView and StringBuilder to use size_t instead of int for lengths.
Obviously a lot of code needs to change as a result of this.
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 :^)
This patch adds these I/O counters to each thread:
- (Inode) file read bytes
- (Inode) file write bytes
- Unix socket read bytes
- Unix socket write bytes
- IPv4 socket read bytes
- IPv4 socket write bytes
These are then exposed in /proc/all and seen in SystemMonitor.
Previously it was not possible to see what each thread in a process was
up to, or how much CPU it was consuming. This patch fixes that.
SystemMonitor and "top" now show threads instead of just processes.
"ps" is gonna need some more fixing, but it at least builds for now.
Fixes#66.
SystemServer can now create sockets on behalf of services before spawning any
of them, and pass the open socket fd as fd 3. CLocalServer gains a method to
complete the takeover and listen on the passed fd.
This is not used by any services at the moment.
Client-side connection objects must now provide both client and server
endpoint types. When a message is received from the server side, we try
to decode it using both endpoint types and then send it to the right
place for handling.
This now makes it possible for AudioServer to send unsolicited messages
to its clients. This opens up a ton of possibilities :^)
When adding a widget to a parent, you don't always want to append it to
the set of existing children, but instead insert it before one of them.
This patch makes that possible by adding CObject::insert_child_before()
which also produces a ChildAdded event with an additional before_child
pointer. This pointer is then used by GWidget to make sure that any
layout present maintains the correct order. (Without doing that, newly
added children would still be appended into the layout order, despite
having a different widget sibling order.)
This patch adds a limit of 200 unsent messages per client. If a client
does not handle its incoming messages and we manage to queue up 200
messages for it, we'll now disconnect that client. :^)
If an IPC client is giving us EAGAIN when trying to send him a message,
we now queue up the messages inside the CoreIPCServer::Connection and
will retry flushing them on next post/receive.
This prevents WindowServer from freezing up when one of its clients is
not taking care of its incoming messages.
Ports/.port_include.sh, Toolchain/BuildIt.sh, Toolchain/UseIt.sh
have been left largely untouched due to use of Bash-exclusive
functions and variables such as $BASH_SOURCE, pushd and popd.
This patch adds three separate per-process fault counters:
- Inode faults
An inode fault happens when we've memory-mapped a file from disk
and we end up having to load 1 page (4KB) of the file into memory.
- Zero faults
Memory returned by mmap() is lazily zeroed out. Every time we have
to zero out 1 page, we count a zero fault.
- CoW faults
VM objects can be shared by multiple mappings that make their own
unique copy iff they want to modify it. The typical reason here is
memory shared between a parent and child process.
This makes it so that "on_connected" always gets called first.
Since accepted sockets are connected before construction, they have
to manually set CSocket::m_connected.
GEventLoop was just a dummy subclass of CEventLoop anyway. The only
thing it actually did was make sure a GWindowServerConnectionw was
instantiated. We now take care of that in GApplication instead.
CEventLoop is now non-virtual and a little less confusing. :^)
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.
We were only deleting the pointee when the ObjectPtr was destroyed.
If the ObjectPtr is cleared before that, we should also delete the
pointee. This is not the most important class to get right, since
it will go away as soon as we're able to switch to RefPtr.