Use this to implement incremental resizing for Terminal so that we only
ever resize to fit a perfect number of rows and columns.
This is very nice. :^)
The algorithm I came up with is O(n^2) but given the small numbers of rects
we're typically working with, it doesn't really matter. May need to revisit
this in the future if we find ourselves with a huge number of rects.
This patch also adds a Format concept to GraphicsBitmap. For now there are
only two formats: RGB32 and RGBA32. Windows with alpha channel have their
backing stores created in the RGBA32 format.
Use this to make Terminal windows semi-transparent for that comfy rice look.
There is one problem here, in that window compositing overdraw incurs
multiple passes of blending of the same pixels. This leads to a mismatch in
opacity which is obviously not good. I will work on this in a later patch.
The alpha blending is currently straight C++. It should be relatively easy
to optimize this using SSE instructions.
For now I'm just happy with the cute effect. :^)
This mistake created an incredible amount of confusion. We would allocate
a slightly too small Painter on the stack and then invoke its constructor,
overwriting whatever came after it on the stack.
This is a monster patch that required changing a whole bunch of things.
There are performance and stability issues all over the place, but it works.
Pretty cool, I have to admit :^)
I'm going with a global top-of-the-screen menu instead of per-window menus.
The basic idea is that menus will live in the WindowServer and clients can
create menus via WindowServer requests.
To facilitate listening for action on arbitrary file descriptors,
I've added a GNotifier class. It's quite simple but very useful:
GNotifier notifier(fd, GNotifier::Read);
notifier.on_ready_to_read = [this] (GNotifier& fd) {
// read from fd or whatever else you like :^)
};
The callback will get invoked by GEventLoop when select() says we
have something to read on the fd.
My needs are really quite simple, so I'm just going to add what I need
as I go along. The first thing I needed was a simple box layout with
widgets being able to say whether they prefer fixed or fill for both
their vertical and horizontal sizes.
I also made a simple GStatusBar so FileManager can show how many bytes
worth of files are in the current directory.
This widget is far from finished, but it's off to a good start.
Also added a GResizeEvent and GWidget::resize_event() so that widgets
can react to being resized.
Let GButton have an optional icon (GraphicsBitmap) that gets rendered in the
middle of the button if present.
Also add GraphicsBitmap::load_from_file() which allows mmap'ed RGBA32 files.
I wrote a little program to take "raw" files from GIMP and swizzle them into
the correct byte order.
Font now uses the same in-memory format as the font files we have on disk.
This allows us to simply mmap() the font files and not use any additional
memory for them. Very cool! :^)
Hacking on this exposed a bug in file-backed VMObjects where the first client
to instantiate a VMObject for a specific inode also got to decide its size.
Since file-backed VMObjects always have the same size as the underlying file,
this made no sense, so I removed the ability to even set a size in that case.
This exposed a serious race condition in page_in_from_inode().
Reordered the logic and added a paging lock to VMObject.
Now, only one process can page in from a VMObject at a time.
There are definitely ways to optimize this, for instance by making
the locking be per-page instead. It's not something that I'm going
to worry about right now though.
This only works with the userspace build of SharedGraphics so far.
It's also very slow at loading fonts, but that's easy to fix.
Let's put fonts in /res/fonts/.