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! :^)
m_roll_notes[] is an array of 2 bools, pressed and playing. A roll note
is highlighted if it is pressed or in the currently playing column, but
the note is only actually played if the roll note is both pressed and
playing.
We change columns every m_tick which is currently 10 frames. The delay
is synchronised with this. change_roll_column() tracks the previous
column and current column to be played. Each roll note in the previous
column is set to "not playing" and the underlying audio note is turned
off if it was pressed. For the current column, each roll note is set to
playing and the underlying audio note is turned on if pressed.
Rather than checking key codes and mouse positions, we should have a
more general way to play notes. You can call note() either with a
KeyCode or a PianoKey directly.
Additionally, m_note_on[] is now an array of integers instead of bools.
This allows multiple sources to play a note. This is kind of like a
"reference counted note": two sources can increment the note and it will
only turn off once they have both decremented it back to 0.
We are now only using keys[] to prevent multiple consecutive calls to
keydown_event() (when a key is held), since that would result in playing
a note many times.
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.
We now try to open image files dropped on us from FileManager. :^)
The QuickShow code is not exactly well-factored, and should be fixes up
to not do the same thing twice, etc.
Every process keeps its own ELF executable mapped in memory in case we
need to do symbol lookup (for backtraces, etc.)
Until now, it was mapped in a way that made it accessible to the
program, despite the program not having mapped it itself.
I don't really see a need for userspace to have access to this right
now, so let's lock things down a little bit.
This patch makes it inaccessible to userspace and exposes that fact
through /proc/PID/vm (per-region "user_accessible" flag.)
The squad is complete :^)
You can find the equation for the triangle wave here:
https://en.wikipedia.org/wiki/Triangle_wave
We're using this one:
|x mod 4 - 2| - 1
Modifications have been made to correct the frequency and phase:
|(4x + 1) mod 4 - 2| - 1
The white noise is generated by calling rand() and dividing it by
RAND_MAX to get a value from 0 to 1. Then it's adjusted to fit between
-1 and 1.
This adds a context menu to the TreeView with the ability to copy/paste, create
new directories, etc. This does not address the issue mentioned above where
using the global application shortcut does not apply to whatever view has
focus.
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.
Ref: #826
Right-clicking a directory no longer has the "Open in TextEditor" entry.
Right-clicking the directory view now allows you to create a new directory.
Currently, when `set_text()` is called on GTextDocument a change is
triggered and all clients registered get a document_did_set_text
call. This in turn causes the TextEditorWidget to mark the document
as dirty even on the first open, which makes for a weird experience.
This is a tiny bar at the left of the taskbar where you can put
your most used apps to launch them with a single click. In a way,
it's another replacement for the Launcher, in addition to the app
menu. Unlike the launcher and the menu, it's not meant to be the
primary way to launch apps; it's only a faster way to launch a few
most often used utilities.
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. :^)
Fixes#825
The logic already existed. I just moved it to a separate lambda then added it
to the appropriate action. Note that when the tree view refreshes, it seems to
randomly open trees. I would like to fix this in a separate PR.
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.
This opens the source of the current document in TextEditor.
For file:// URLs, we open the local file, but for all other protocols,
a temporary file is generated, containing the document source.
Longer-term we should build some kind of viewer into the Browser app
instead. That would avoid silly problems like how this forgets to
delete the temporary files, for instance :^)