If a window which has an active modal window is focused, the modal
window starts blinking. In this case, the window (and modal) should
still be focused. For this, the order of the checks in
process_mouse_event_for_window has to be changed.
This fixes#8183.
This commit addresses two issues:
1. If you play a 96 KHz Wave file, the slider position is incorrect,
because it is assumed all files are 44.1 KHz.
2. For high-bitrate files, there are audio dropouts due to not
buffering enough audio data.
Issue 1 is addressed by scaling the number of played samples by the
ratio between the source and destination sample rates.
Issue 2 is addressed by buffering a certain number of milliseconds
worth of audio data (instead of a fixed number of bytes).
This makes the the buffer size independent of the source sample rate.
Some of the code is redesigned to be simpler. The code that did the
book-keeping of which buffers need to be loaded and which have been
already played has been removed. Instead, we enqueue a new buffer based
on a low watermark of samples remaining in the audio server queue.
Other small fixes include:
1. Disable the stop button when playback is finished.
2. Remove hard-coded instances of 44100.
3. Update the GUI every 50 ms (was 100), which improves visualizations.
When using `aplay` to play audio files with a sample rate of 96000,
there were occasional one-second gaps in playback. This is
because the Audio::ClientConnection sleeps for a full second when
the audio buffer is full.
One second is too long to sleep, especially for high-bitrate files.
Changing the sleep to a more reasonable value like 100 ms ensures
we attempt to enqueue again before the audio buffer runs empty.
Prior code in `WavLoader::get_more_samples()` would attempt to
read the requested number of samples without actually checking
whether that many samples were remaining in the stream.
This was the cause of an audible pop at the end of a track, due
to reading non-audio data that is sometimes at the end of a Wave file.
Now we only attempt to read up to the end of sample data, but no
further.
Also, added comments to clarify the meaning of "sample", and how it
should be independent of the number of channels.
Since MultiScaleBitmaps only loads icons for the scales in use, we need
to unconditionally reload them so that we pick up the correct bitmaps
for a scale that hasn't been previously used.
This enables the shot utility to capture all screens or just one, and
enables the Magnifier application to track the mouse cursor across
multiple screens.
This enables rendering of mixed-scale screen layouts with e.g. high
resolution cursors and window button icons on high-dpi screens while
using lower resolution bitmaps on regular screens.
This sets the stage so that DisplaySettings can configure the screen
layout and set various screen resolutions in one go. It also allows
for an easy "atomic" revert of the previous settings.
If there are any screens that are detached from other screens it would
not be possible to get to them using the mouse pointer. Also make sure
that none of the screens are overlapping.
We were calculating the old window rectangle after changing window
states that may affect these calculations, which sometimes resulted
in artifacts left on the screen, particularily when tiling a window
as this now also constrains rendering to one screen.
Instead, just calculate the new rectangle and use the window's
occlusion information to figure out what areas need to be invalidated.
When a window is maximized or tiled then we want to constrain rendering
that window to the screen it's on. This prevents "bleeding" of the
window frame and shadow onto the adjacent screen(s).
This allows WindowServer to use multiple framebuffer devices and
compose the desktop with any arbitrary layout. Currently, it is assumed
that it is configured contiguous and non-overlapping, but this should
eventually be enforced.
To make rendering efficient, each window now also tracks on which
screens it needs to be rendered. This way we don't have to iterate all
the windows for each screen but instead use the same rendering loop and
then only render to the screen (or screens) that the window actually
uses.
These helpers will be useful in preparation for supporting multiple
displays, e.g. to measure distances to other screens or figure out
where rectangles are located relative to each other.
Some objects need to perform tasks during construction that require
the object to be fully constructed, which can't be done in the
constructor. This allows postponing such tasks into a did_construct
method that will be called right after the object was fully
constructed.
This is so that we can reliably allocate them in a template function,
e.g. in ordinary_create_from_constructor():
global_object.heap().allocate<T>(
global_object, forward<Args>(args)..., *prototype);
The majority of objects already take the prototype as the last argument,
so I updated the ones that didn't.
Value.{cpp,h} has become a dumping ground, let's change that.
Things that are directly related to Values (e.g. bitwise/binary ops,
equality related functions) can remain, but everything else that's not a
Value or Object method and globally required (not just a static function
somewhere) is being moved.
Also convert to east-const while we're here.
I haven't touched IteratorOperations.{cpp,h}, it seems fine to still
have those separately.
PR #5665 updated TextEditor to open files at a specific line/column
location using the file:line:col argument, rather than the -l flag.
This change updates LaunchServer to use that convention, though note it
does only pass the line number and not a column number, as per all
previous behaviour.
If we have a VGA-capable graphics adapter that we support, we should
prefer it over any legacy VGA because we wouldn't use it in legacy VGA
mode in this case.
This solves the problem where we would only use the legacy VGA card
when both a legacy VGA card as well as a VGA-mode capable adapter is
present.
Better information is now shown to the player. Instructions are shown
when first loading the program, and any available scores are shown on
the game over screen.
Problem:
- Now that a generic free-function form of `find_if` is implemented
the code in `any_of` is redundant.
Solution:
- Follow the "don't repeat yourself" mantra and make the code DRY by
implementing `any_of` in terms of `find_if`.
Unfortunately this patch is quite large.
The main functionality included are a BTree index implementation and
the Heap class which manages persistent storage.
Also included are a Key subclass of the Tuple class, which is a
specialization for index key tuples. This "dragged in" the Meta layer,
which has classes defining SQL objects like tables and indexes.
This patch adds the basic dynamic value classes used by the SQL Storage
layer. The most elementary class is Value, which holds a typed Value
which can be converted to standard C++ types. A Tuple is a collection
of Values described by a TupleDescriptor, which specifies the names,
types, and ordering of the elements in the Tuple.
Tuples and Values can be serialized and deserialized to and from
ByteBuffers. This is mechanism which is used to save them to disk.
Tuples are used as keys in SQL indexes and rows in SQL tables.
Also included is a test file.