The Settings app is basically a viewer for the Settings app category
anyway, so let's just direct users there instead of having the various
settings apps in the start menu.
We were missing to account for areas that are not covered by any
window. If any of these areas are covered by an overlay we need to
render the wallpaper into transparency and also render the overlay
over them.
This fixes not rendering overlays properly when e.g. the FileManager
(desktop) crashed as there is no longer any window underneath.
The upcoming 'Delete' operation has no destination, so this was the
best solution we could come up with for now. Perhaps ArgsParser
could support sub-commands, so we would define 'Copy', 'Move' and
'Delete' each as sub-commands with their own argument definitions.
That would make things like git's variety of commands possible.
You can now list multiple files or directories and they will all be
copied to the destination. :^)
Note that this means you can pass the same file or directory multiple
times. It runs fine, just means that it does unnecessary work. But
figuring out if a file is already queued is probably more hassle than
it's worth, if it's even possible at all due to symlinks.
When changing the theme, there were two Core::ConfigFile instances
(one class scoped -- m_config and one function scoped -- wm_config)
fighting over the file, resulting in not saving the new theme name
to the config. :^(
This makes WindowServer remember selected theme from the menu
after reboot!
If a screen layout cannot be applied, instead of failing to start
WindowServer try to fall back to an auto-generated screen layout with
the devices that are detected.
Also, be a bit smarter about changing the current screen layout.
Instead of closing all framebuffers and bringing them back up, keep
what we can and only change resolution on those that we need to change
them on. To make this work we also need to move away from using an
array of structures to hold compositor related per-screen data to
attaching it to the Screen itself, which makes re-using a screen much
simpler.
This feels a bit awkward right now, and needs code duplication - I think
adding a mechanism to the AppFile class to run the executable would be
neat, especially if we add an arguments field to app files - but this
will do for now.
We only need to re-draw the item being selected and the item being
deselected. We also don't care anymore if applets were added or
removed as we no longer have a global menu bar.
We were re-rendering areas that were considered transparency areas even
though they weren't transparency areas or were occluded by opaque
areas.
In order to fix this, we need to be a bit smarter about what is above
and below any given window. Even though a window may have transparent
areas, if those are occluded by opaque window areas on top they are
not actually any areas that should be rendered at all. And the opposite
also applies, opaque window areas for windows below that are occluded
by transparent areas, do need to be rendered as transparency. This
solves the problem of unnecessary transparency areas.
The other problem is that we need to know what areas of a window's
dirty rectangles affect other windows, and where. Basically any
opaque area that is somehow below a transparent area that isn't
otherwise occluded, and any transparent area above any other window
area (transparent or opaque) needs to be marked dirty prior to
composing. This makes sure that all affected windows render these
areas in the correct order. To track these, we now have a map of
affected windows and the rectangles that are affected (because not all
of that window's transparency areas may be affected).
This implements window stealing in WindowServer, which allows clients
to mark a window they own as 'stealable' by another client. Indicating
that the other client may use it for any purpose.
This also updates set_window_parent_from_id so that the client must
first mark its window as stealable before allowing other clients to
use it as a parent.
This transitions from synchronous IPC calls to asynchronous IPC calls
provided through a synchronous interface in LibFileSystemAccessClient
which allows the parent Application to stay responsive.
It achieves this with Promise which is pumping the Application event
loop while waiting for the Dialog to respond with the user's action.
LibFileSystemAccessClient provides a lazy singleton which also ensures
that FileSystemAccessServer is running in the event of a crash.
This also transitions TextEditor into using LibFileSystemAccessClient.
A SPICE agent communicates with the host OS to provide nifty features
like clipboard sharing :^)
This patch implements only plain-text clipboard sharing.
See: github.com/freedesktop/spice-protocol/blob/master/spice/vd_agent.h
If a user picks a file which can't be opened for some reason, we should
still return the value, so client applications can report the error
along with the chosen filepath.
If the device requires a flush and we modify the front buffer, we need
to flush those changes to the front buffer. This makes the flashing
work using the VirtIOGPU.
Also fix a minor bug where we flushed the front buffer instead of
the back buffer after flipping, which caused the VirtIOGPU to not work
as expected when using the SDL backend and disabling buffer flipping.
Adds new service FileSystemAccessServer which allows programs to
request a file descriptor for any file on the file system.
The user can be prompted to choose the path with a FilePicker, or the
path can be provided by the application which will show a MessageBox
showing the pid and name of the calling process and allows the user to
approve or deny the request.
The windows in the background are ignored when the window is fullscreen.
However, we still would like to see the background if that window is
transparent.
* LibGUI: Verify m_window_id is not-zero in set_maximized
Window::set_maximized requires non-zero window id to be a valid call,
i.e. calling Window::show beforehand. A verify statement before the
server call can help developers by hinting correct usage.
* LibGUI: Paint background when the fullscreen window is transparent
The windows in the background are ignored when the window is fullscreen.
However, we still would like to see the background if that window is
transparent.
* Userland: Add ability to capture rectangular region in shot
A click and drag selectable, transparent, fullscreen window is
displayed with the command line argument -r for screenshots.
This makes it easy for the user to just throw the mouse at the corner
of the screen and obtain the desired outcome (eg. opening the start
menu), without having to precisely position the cursor over one of the
buttons.
This patch adds a missing minimize check for highligted windows in
WindowStack::for_each_visible_window_of_type_from_front_to_back().
Minimized windows should not be treated as visible in this context.
Previously, iterating through each visible Window when recomputing
occlusions in the Compositor would cause a crash if a highlighted
Window is also minimized at the same time. As the WindowSwitcher
currently highligts Windows even when they are minimized, opening
it while any Window is minimized would cause WindowServer to crash.
This patch removes the background behind window icons
in the WindowSwitcher which looked like it was being
rendered incorrectly (without alpha) previously.
This patch introduces the SQLServer system server. This service is
supposed to be the only process/application talking to database storage.
This makes things like locking and caching more reliable, easier to
implement, and more efficient.
In LibSQL we added a client component that does the ugly IPC nitty-
gritty for you. All that's needed is setting a number of event handler
lambdas and you can connect to databases and execute statements on them.
Applications that wish to use this SQLClient class obviously need to
link LibSQL and LibIPC.
GCC likely has a builtin intrinsic that evaluates the operation at
compile-time, even if the `LibM` is not declared as constexpr. Clang,
however, does not like it, and it failed to compile this code.
We already do this in most places, so the style should be consistent.
Also, Clang does not like it, as this could cause an unexpected compile
error if some statements are added to the default label or a new label
is added above it.
While structs being forward declared as classes is not strictly an
issue, Clang complains as this is not portable code, since some ABIs
treat classes declared as `class` and `struct` differently.
It's easier to fix these than to reason about explicitly disabling
another warning.
It might be the case that we are passing non-movable/non-copyable things
through IPC. In this case, Clang will emit a warning as it can't
generate the requested default move/copy ctor for the IPC message.
To fix this, we use a `#pragma` to make the compiler silently ignore our
request.
The same was the case with the three-way comparison in `Screen`. Since
we don't use the three-way comparison operator anywhere else in our
codebase, we simply use the `==` operator instead.
This fixes a bug with menu keyboard navigation. If you pressed the right
arrow to enter a submenu, then the left arrow to exit the submenu, then
right and left again it would leave no menu item selected.
Because descending into the submenu wasn't making it the current menu,
when you press the left arrow it couldn't find the "current menu" in the
stack, so didn't know what menu to pop back to.
It was an accident that it worked the first time you navigated into the
menu. Selecting the parent item also opened the submenu, and opening
an already open menu sets it as the current menu. After closing the
submenu with the left arrow, it is no longer already open, so it wasn't
getting set as the current menu.
Before this change, invalidating any rect in a WindowFrame would cause
the entire window (including frame & drop shadow) to get invalidated,
leading to copious amounts of overdraw when mousing over menubars,
titlebars, and window buttons.
We now simply allow the partial frame invalidations through to the
window's dirty rects collection and the compositor takes care of it.
ec6debb changed item_index_at to return -1 when hovering over a
separator. The intent was to not send the separator to clients for
MenuItemEntered.
However, this had the unintented consequence of not closing the submenu
when you hover over a separator. Submenus ignore when the item index is
-1 in order to leave the menu open when you move the mouse outside. This
ends up leaving the submenu open without the highlight to show what menu
item the submenu belongs to.
A slightly less severe consequence is that pressing the up or down arrow
key in such a situation would now go the top or bottom of the menu
rather than the item above or below the separator.
We now push the special casing of separators into set_hovered_index so
that the rest of the code behaves as it did before ec6debb.
Previously, this mode would flash flush/repaint rects in yellow for
however it long it took for the compositor to replace the yellow with
the final image instead.
Now we usleep() for 10 ms when flashing, so you get a chance to see
the yellow. This immediately makes "flash flush" mode super useful. :^)
This patch adds the concept of a window being "Pinnable" (always drawn
on top of other windows). This can be toggled through a new checkable
action in the top left corner's window menu.
Because window states and various flags can affect the windows'
rendered areas it's safer to use the last computed occlusion rectangles
to invalidate areas on the screen that may have to be re-rendered due
to e.g. a window size change.
Fixes#6723
Depending on the driver, the second buffer may not be located right
after the first, e.g. it may be page aligned. This removes this
assumption and queries the driver for the appropriate offset.
Some devices may require DMA transfers to flush the updated buffer
areas prior to flipping. For those devices we track the areas that
require flushing prior to the next flip. For devices that do not
support flipping, but require flushing, we'll simply flush after
updating the front buffer.
This also adds a small optimization that skips these steps entirely for
a screen that doesn't have any updates that need to be rendered.
The only remaining sync call from client to server is now the call
that switches a window's backing store. That one actually relies on
the synchronization to hand over ownership of the backing stores,
so it has to stay synchronous for now.
Differentiates between normal minimization and hidden windows. A window
which is hidden is still minimized, but can be seen as another stage
of being minimized.
Also, make it return a reference as aside from only three special
situations (creating, destroying, and moving a window between stacks)
a window should always be on a window stack. Any access during those
brief situations would be a bug, so we should VERIFY this.
This solves two problems:
* A window was sometimes deemed occluded when the window rect was
entirely covered by other rectangles, transparent or opaque. This
caused a window to stop rendering even if a small portion was still
visible, e.g. when it was merely covered by a window shadow.
* The window switcher is interested in window updates even when a
window is entirely covered by another one, or when it is on another
desktop. This forces windows to be not occluded in those cases.
When using the Super+Tab hotkey then all windows will be displayed,
and we will switch to another virtual desktop if needed.
When using the Alt+Tab hotkey then only the windows on the current
desktop will be displayed.
This also adds the ability to query how many virtual desktops are
set up, and for the Taskbar to be notified when the active virtual
desktop has changed.
This creates a 2-dimensional array of WindowStack instances, one for
each virtual desktop. The main desktop 0,0 is the main desktop, which
is the desktop used for all stationary windows (e.g. taskbar, desktop).
When adding windows to a desktop, stationary windows are always added
to the main desktop.
When composing the desktop, there are usually two WindowStacks
involved. For stationary windows, the main desktop will be traversed,
and for everything else the current virtual desktop will be iterated.
Iteration is interweaved to preserve the correct order. During the
transition animation, two WindowStacks will be iterated at the same
time.
This removes StringView::find_first_of(char) and find_last_of(char) and
replaces all its usages with find and find_last respectively. This is
because those two methods are functionally equivalent.
find_{first,last}_of should only be used if searching for multiple
different characters, which is never the case with the char argument.
This also adds the [[nodiscard]] to the remaining find_{first,last}_of
methods.
The LexicalPath instance methods dirname(), basename(), title() and
extension() will be changed to return StringView const& in a further
commit. Due to this, users creating temporary LexicalPath objects just
to call one of those getters will recieve a StringView const& pointing
to a possible freed buffer.
To avoid this, static methods for those APIs have been added, which will
return a String by value to avoid those problems. All cases where
temporary LexicalPath objects have been used as described above haven
been changed to use the static APIs.
Since this is always set to true on the non-default constructor and
subsequently never modified, it is somewhat pointless. Furthermore,
there are arguably no invalid relative paths.
Add `inspect_dom_tree` to WebContentServer and 'did_get_dom_tree' to
WebContentClient.
These two async methods form a request & response for requesting a JSON
representation of the Content's DOM tree.
The time interval for animations is most often described as `duration`
in animation contexts and the `WindowServer::Animation` class
should reflect that.
The menus always thought they were being outside of the main screen,
which caused them to be left and/or top aligned. This also fixes the
calculation of the available space by using the screen rectangle where
it will be displayed.
We care about showing 'Assistant' app as fast as possible when the
hotkey is pressed. In order to do that, we can parse the `.af` file
ahead of time and have it ready to use.
To make Assistant useful we need a way to quickly trigger it. I've
added a new specialized event coming from the window server for when a
user is holding down 'Super' and hits 'Space'.
The Taskbar will be able to listen for this event and spawn a new
instance of the Assistant if it's not already running.
Since being tiled means we restrict rendering a window to the screen it
is on (so that we don't "bleed" into an adjacent screen), we need to
untile it if the window either can't fit into the screen, or it is
detached from the screen edges.
The launch_origin_rect parameter to create_window() specifies where on
screen the window was launched from. It's optional, but if you provide
it, the new window will have a short wireframe animation from the origin
to the initial window frame rect.
GUI::Window looks for the "__libgui_launch_origin_rect" environment
variable. Put your launch origin rect in there with the format
"<x>,<y>,<width>,<height>" and the first GUI::Window shown by the app
will use that as the launch origin rect.
Also it looks pretty neat, although I'm sure we can improve it. :^)
This patch adds the WindowServer::Animation class, which represents
a simple animation driven by the compositor.
An animation has a length (in milliseconds) and two hooks:
- on_update: called whenever the animation should render something.
- on_stop: called when the animation is finished and/or stopped.
This patch also ports the window minimization animation to this new
mechanism. :^)
We regularily need to flush many rectangles, so instead of making many
expensive ioctl() calls to the framebuffer driver, collect the
rectangles and only make one call. And if we have too many rectangles
then it may be cheaper to just update the entire region, in which case
we simply convert them all into a union and just flush that one
rectangle instead.
This fixes a regression where the geometry label isn't updating even
though the window geometry had changed because the geometry label's
location isn't changing.
An Overlay is similar to a transparent window, but has less overhead
and does not get rendered within the window stack. Basically, the area
that an Overlay occupies forces transparency rendering for any window
underneath, which allows us to render them flicker-free.
This also adds a new API that allows displaying the screen numbers,
e.g. while the user configures the screen layout in DisplaySettings
Because other things like drag&drop or the window-size label are not
yet converted to use this new mechanism, they will be drawn over the
screen-number currently.
My previous PR had a small error in rebasing and removed a line in
open_file_url. This caused opening text files from the terminal to
always open with an empty TextEditor.
This commit fixes that problem!
This commit gets rid of hard coded file handlers in Launcher.cpp in
favor of using values in the LaunchServer.ini config file.
The previous commit adds checks for the existence of handler programs
while registering handlers. This commit takes advantage of that and
ensures that LaunchServer will not attempt to open a file with a
nonexistent program and can properly report failure before spawning a
new child process.
Resolves#8120
This adds checks in load_handlers() and load_config() to see if the
programs specified in the config files exist before registering them as
handlers.
Resolves#8121
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.
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.
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.
Some paths of the mouse event processing code will upgrade the event
from a regular MouseDown to a MouseDoubleClick. That's why we were
passing `MouseEvent&` everywhere.
For the paths that don't need to do this, passing `MouseEvent const&`
reduces the cognitive burden a bit, so let's do that.
Instead of plumbing a Window* through the entire mouse event processing
logic, just do a hit test and say that the window under the cursor is
the hovered window.
It's funny how much easier this is now that we have a way to hit test
the entire window stack with one call.
Move the logic for processing a mouse event that hits a specific window
into its own function.
If the window is blocked by a modal child, we now get that out of the
way first, so we don't have to think about it later.
Even if a window is in fullscreen mode, we still want hit testing to
walk the window stack. Otherwise child windows of the fullscreen
window will not receive mouse events.
The button widgets internally rendered by WindowServer are only used
in titlebars, and require a bit of mouse event handling. Instead of
mixing it with the window-oriented mouse event handling, get the
button event stuff out of the way first.
We were forgetting to preserve the m_drag and m_mime_data members of
WindowServer::MouseEvent when making a translated copy.
This didn't affect any reachable code paths before this change.
If a window is currently actively tracking input events (because
sent it a MouseDown and haven't sent it a MouseUp yet), we now simply
send mouse events to that window right away before doing any other
event processing.
This makes it much easier to reason about mouse events.
Instead of just answering hit/no-hit when hit testing windows, we now
return a HitTestResult object which tells you which window was hit,
where it was hit, and whether you hit the frame or the content.
This feature had been there since early on and was not actually useful
for anything. I just added it because it was fun. In retrospect, it's
not a very good feature and I only ever activated it by accident.
This patch moves the window stack out of WindowManager and into its own
WindowStack class.
A WindowStack is an ordered list of windows with an optional highlight
window. The highlight window mechanism is used during Super+Tab window
switching to temporarily bring a window to the front.
This is mostly mechanical, just moving the code to its own class.
Remove the confusingly-named inflate_for_shadow() function and inline
its logic into render_to_cache(). And remove the m_shadow_offset
member variable since it was only needed locally in one place.
Also improve some variable names to make it more understandable what
is going on.
This way we don't have to allocate this at runtime. I'm intentionally
not using static constexpr here because that would put the variable
into the .rodata segment and would therefore increase the binary by
4kB.
The old code also failed to free() the buffer in the destructor, however
that wasn't much of an issue because the Mixer object exists throughout
the program's entire lifetime.
Let clients manage their own window ID's. If you try to create a new
window with an existing ID, WindowServer will simply disconnect you
for misbehaving.
This removes the need for window creation to be synchronous, which
means that most GUI applications can now batch their entire GUI
initialization sequence without having to block waiting for responses.
This enables the WebServer to run protected by a username and password.
While it isn't possible to access such a protected server from inside
Serenity as of now (because neither the Browser nor pro(1) support
this), this may very well be the case in the future. :^)
This moves the configuration of the web server, which currently only
consists of the root path, into a new class, Configuration. Since the
configuration is global and not per client, it is accessed by a
singleton getter.
This change simplifies future extensions of the configurable parameters.
This changes the Client::set_error_response() to not take a "message"
anymore. It now uses the canonical reason phrase which is derived from
the response code.
This adds trailing slashes to all links to directories (when listing the
directory contents). This avoids the redirect that would otherwise
happen when browsing to those directories.
In the web server root directory, ".." has to be handled specially,
since everything above it does not exist from the point of view of the
user. The most sensible thing to do is to make ".." equal to ".". This
is also what ls(1) does for "/" and what "http://localhost/../"
evaluates to.
This also fixes a bug where stat() would fail on the directory above the
root directory, since it hasn't been unveiled for the process.
This adds a FileWatcher to the LookupServer which watches '/etc/hosts'
for changes during runtime and reloads its contents. If the file is
deleted, m_etc_hosts will be cleared.
Since we now need to access '/etc/hosts' later during runtime, it needs
to be unveiled with read permissions.
This reworks the LookupServer::load_etc_hosts() method to use the
IPv4Address APIs instead of trying to parse an IPv4 address itself.
It also adds a few error checks for invalid entries in /etc/hosts,
trims away leading and trailing whitespace from lines and tries to use
StringView over String.
This patch moves the magnifier rect computation over to the server side
to ensure that the mouse cursor position and the screen image never get
out of sync.
By moving the logic to determine what window areas (shadow, frame,
content) into WindowFrame::opaque/transparent_render_rects we can
simplify the occlusion calculation and properly handle more
arbitrary opaque/transparent areas.
This also solves the problem where we would render the entire
window frame as transparency only because the frame had a window
shadow.
Previously, AK::Function would accept _any_ callable type, and try to
call it when called, first with the given set of arguments, then with
zero arguments, and if all of those failed, it would simply not call the
function and **return a value-constructed Out type**.
This lead to many, many, many hard to debug situations when someone
forgot a `const` in their lambda argument types, and many cases of
people taking zero arguments in their lambdas to ignore them.
This commit reworks the Function interface to not include any such
surprising behaviour, if your function instance is not callable with
the declared argument set of the Function, it can simply not be
assigned to that Function instance, end of story.
Now that Desktop.h includes Services/Taskbar/TaskbarWindow.h we have
to install Taskbar's header files so that Desktop.h can be used in
ports or when building software in-target.
This replaces ctype.h with CharacterType.h everywhere I could find
issues with narrowing conversions. While using it will probably make
sense almost everywhere in the future, the most critical places should
have been addressed.
Previous to this commit, if a `Window` wanted to set its width or height
greater than `INT16_MAX` (32768), both the application owning the Window
and the WindowServer would crash.
The root of this issue is that `size_would_overflow` check in `Bitmap`
has checks for `INT16_MAX`, and `Window.cpp:786` that is called by
`Gfx::Bitmap::create_with_anonymous_buffer` would get null back, then
causing a chain of events resulting in crashes.
Crashes can still occur but with `VERIFY` and `did_misbehave` the
causes of the crash can be more readily identified.