We want to update the input focus only if the pointer is moved. Due to
that, AbstractClient::enterEvent() checks the last seen pointer position
to decide whether the window needs to be focused.
The issue is that when the pointer moves from a decoration to a surface,
the cached pointer position will be updated to the current pointer
position, and thus the check in AbstractClient::enterEvent() will fail.
We need to update the cached pointer position only if there is a focused
decoration.
When a GPU has no outputs attached we need to release all resources and
close the fd to allow the driver to completely power down the GPU. This
is also required to allow the driver to be unloaded for VFIO.
Xcursors don't support hidpi so if a hidpi cursor is needed, kwin will
scale the desired size by the scale factor and ask Xcursor helpers to
load a theme with the given name and the size.
However, the theme loading code doesn't take into account that Xcursor
theme loading helpers may not return cursor sprites of size size * scale
if the theme has no such a size.
For example, if the cursor theme only provides 24, 36, and 48 sizes and
kwin attempts to load cursors of size 48 with a scale factor of 2, we
will get cursors of size 48 instead of 96. Unfortunately, this will
result in the issue where the cursor shrinks when hovering decorations
because kwin doesn't know that the effective scale factor (1) is
different from the requested scale factor (2).
In order to fix loading of HiDPI cursors, we need to approximate the
effective scale factor of every cursor sprite as we load it.
The WorkspaceWrapper::screenResized() signal relies on the QDesktopWidget
class, which is deprecated. Another issue with that signal is that it
uses integers to represent screens. We need to minimize the amount of int
based screen api and prefer more QScreen or AbstractOutput APIs because
the former get completely broken if the output layout changes.
Since we gain not a lot from porting WorkspaceWrapper::screenResized()
away from QDesktopWidget to something else and we don't use this signal
in any of our scripts, this change deprecates the screenResized signal
in favor of manual tracking of QScreen::geometryChanged signal.
When keyboard_grab is implemented, if we reset the inputmethod context
on any key, input method will not get keyboard input and will not be
able to use it.
Since the scripted effects were ported to QJSEngine, it's possible now to
use ECMAScript 2015 perks such as classes, let and const.
This change ports the scale effect to some ES6 features to make the code
neater.
Call ::updateInputPanelState when necessary (instead of a trimmed-down
refreshFrame version.
Actually provide the overlap information when it's available, there's no
need to send wrong information there.
Platform::prepareShutdown() was introduced to work around the issue
where the platform accesses destroyed OutputDeviceInterface objects.
Since we no longer query OutputDeviceInterface for output info, the
Platform::prepareShutdown() function can be dropped.
When we release the buffers that also removes the drm fbs.
This causes failing atomic commits that the atomic code
doesn't (yet) handle correctly, the result is a black
screen when compositing is restarted.
We want to update the inputpanel state on new value which is being set
and not based on the cached value.
Fixes the keyboard going in wrong mode like pre-edit mode when closed
and re-opened.
Most wayland-native apps provide buffers that aren't suitable
for direct scanout; the message usually only spams the log full
without proper reason or useful information
When getting the vector, it requires us to check both if it's not empty
but also that it's not null. I haven't seen it but we were not doing
this check.
Just return an empty vector when there's no devices instead.
Let UdevDevice offer the method we need for sorting instead of just half
of it.
Always sort Udev enumerations, since the alternative is to sort it every
time it's called otherwise.
In the few cases where the framebuffer is needed, we'd get problems
because ioctl(KWIN_FB_NO_VSYNC) fails.
This removes the code entirely to just use a timer to refresh.
BUG: 436053
QPainter::setWindow() doesn't work as we expect if the device pixel
ratio of the paint device is less than 1, for example 0.5 or 0.75.
QPainter only allows the effective device pixel ratios that are greater
than or equal to 1. This restriction probably has to be lifted.
For the time being, this change introduces a helper function that can be
used to determine the scale factor by which QPainter::window() must be
multiplied.
BUG: 432766
Reducing the oppacity of these windows causes them to appear as phantoms
in the corners of the screen. They look quite odd on top of anything else
in the corners of the screen, such as any Plasma panels.
However making them 100% opaque doesn;t work either, since then they
look interactive, but they're not, and can't be made so due to the
scripting API used here.
So our only real option to remove the weirdness is to make them 100%
transparent, and therefore show the entirety of the desktop with no sign
that the effect is in use.
Instead of deleting all blob properties without a valid
blob check for the blob existing before using it. This is
necessary because some properties are needed even without
currently valid blobs.
BUG: 435786
While the session is inactive, the drm master permissions are revoked.
Therefore, we cannot perform things such as modesetting, etc. It also
makes no sense to create or destroy DrmOutput objects.
CCBUG: 435941
This reverts commit 5a22deda3b.
We still need more work to finish the DrmPipeline. At the moment, there
are a few major issues, e.g. some outputs not turning on, output
transforms not working correctly, a crash when changing dpms mode.
Let's merge this change back once all major issues are fixed and after
more testing.
We'd be relying on AbstractEglDrmBackend on calling cleanup but we'd be
doing it when cleanupSurfaces cannot be reached out anymore, turning it
into a half-baked cleanup.
Instead call cleanup from the leaf class destructors.
The last presentation timestamps should be reset when all animations
finish rather than when the effect finishes. Otherwise, the calculated
time diff for the first animation frame will be too big.
BUG: 433471
Showing the panels makes this effect a little bit more integrated
with the desktop. With the panels disabled it creates a separate state,
with the panels enabled it creates a more friendly state with
the effect adding to the already existing experience.
We cannot use Workspace::clientArea() to get the geometry of the screen
as the clientArea() method needs a valid frame geometry. This is not the
case if the layer shell surface is being configured for the first time.
With ksplash migrating to the layer-shell protocol, it no longer
provides an app id. This means that the window class string will be
different, e.g. "ksplashqml " instead of "ksplashqml ksplashqml", and
some effects (login, etc) will stop working as expected.
In order to keep effects working as before, this change adjusts the
window class initialization in WaylandClient so both the resource class
and the resource name are set to the executable file name.
DrmPipeline is what now contains all the drm bits related to
modesetting and presentation, instead of that being in DrmOutput.
This gives a lot more freedom for managing drm resources and
enables far better usage of the atomic API with guaranteed
immutability for failed tests.
At the moment a streamed screen when the screen scale was differnt
buffer scale would render wrong. This change addresses it by
compensating it.
This change compensates it resizing the rendered viewport to their
difference.
BUG: 428594
In this context, the cursor will (almost) always be defined as we set it
as soon as an application is bound to it. We need to show the default
cursor if set_cursor hasn't been called yet. The way to do that is to
check whether the serial is still.
Instead use the device assigned output.
#0 KWin::Toplevel::screen() const (this=0x0) at /home/apol/devel/frameworks/kwin/src/toplevel.cpp:409
#1 0x00007fe60ad9bef9 in KWin::LibInput::Connection::processEvents() (this=0x55d9efc155f0) at kwin/src/libinput/connection.cpp:579
#2 0x00007fe60ad4987c in KWin::InputRedirection::setupLibInput()::$_3::operator()() const (this=0x55d9efc29a70) at kwin/src/input.cpp:2315
The stream object was deleted from a slot connected to its stopStreaming
signal. This is unsafe and can lead to memory corruption and ultimately
crashes when PipWwire streaming is stopped. Use deleteLater instead.
BUG: 428268 435588
screen() only gets updated after AbstractClient::sendToScreen if invoked
by a shortcut or menu (as opposed to moveresize), so we can't use it in
AbstractClient::updateGeometryRestoresForFullscreen as it points to the
old screen.
With the introduction of stripped down window items, the WindowPixmap
objects no longer form a hierarchy. WindowPixmap::children() method was
removed.
Surprisingly, the removal of the children() method didn't result in a
compilation error because the QObject class has a method with the same
name.
Currently, a window pixmap will have no QObject children even if the
associated wayland surface has child sub-surfaces. This may result in
blank thumbnails of apps that use sub-surfaces, e.g. Firefox. In order
to fix that issue, we need to check if there are child items instead.
We'd always get "0x0: something" where the 0x0 is the xcb_window which
obviously doesn't translate.
Instead show the class name so we can easily track what kind of object
we are dealing with.
It's an easy way to show which shell it's using on Wayland, will be
useful in other cases as well.
If a decoration is created for an already mapped maximized window, check
the workspace position to ensure that the window still fits the maximize
area.
BUG: 432326
Currently, output properties are looked up either on the wl_output
object or the output device object. This puts a hard dependency on the
wayland server in the platforms.
This change intends to fix some flaws in the current output
abstractions, and allow creating/destroying wayland-specific globals as
we wish.
With the work done in this patch, the need for the AbstractWaylandOutput
class is unclear, and it might be a good idea to merge it with the base
AbstractOutput class.
This is to ensure that isNormalWindow() returns false for popups. One
could argue that we abuse netwm window types, on the other hand, we
don't know the exact type of popups and NET::Unknown is the closest type.
Re-use Qt's implementation of handling non-Latin layouts here
For full ASCII range support (Alt+`, etc.) Qt needs to be patched still,
see QTBUG-90611
BUG: 375518
I consider this a prerequisite commit to improving the quality of touchpad gestures provided by KWin.
In short, this breaks apart a weird all-in-one class into an std::variant for the different types
of shortcuts in order to make it easier to add new types of global shortcuts. For the byte shavers, this
roughly halves the size of the GlobalShortcut class as well. On top of all this, the code is about half
the size it was before, mostly due to newer C++ concepts being used that allow us to let the compiler
do more work for us.
Currently, we inhibit renderloops when switching to another TTY, and unhibit
when switching back. When we hotplug a display while switched to another TTY,
its renderloop isn't inhibited by default, yet when we switch back, we try
to uninhibit the fresh renderloop, which triggers an assert.
Inhibiting newly created outputs while switched to another TTY fixes this crash.
BUG: 435388
FIXED-IN: 5.21
The connector name is not relevant to applications or
users - expectation is that the same physical monitor always gets the
same name, regardless of how it's connected. If no serial is available,
fall back to the old scheme to prevent multiple connected outputs from
having the same name.
The value that the DrmCrtc::resIndex() function returns is better known
as "pipe index." This change renames the method to match the terminology
used by kernel developers and other compositor developers.
drmModeGetPropertyBlob() may return null and we should handle that. In
addition to that, m_conn is not initialized in DrmConnector so kwin will
crash whenever the connector info is accessed.
This introduces the markedAsZombie signal, which is emitted when the
window is about to become deleted. The X11SurfaceItem uses this signal
to determine when the damage must be destroyed.
Currently, dealing with sub-surfaces is very difficult due to the scene
design being heavily influenced by X11 requirements.
The goal of this change is to re-work scene abstractions to make improving
the wayland support easier.
The Item class is based on the QQuickItem class. My hope is that one day
we will be able to transition to QtQuick for painting scene, but in
meanwhile it makes more sense to have a minimalistic internal item class.
The WindowItem class represents a window. The SurfaceItem class represents
the contents of either an X11, or a Wayland, or an internal surface. The
DecorationItem and the ShadowItem class represent the server-side deco and
drop-shadow, respectively.
At the moment, the SurfaceItem is bound to the scene window, but the long
term plan is to break that connection so we could re-use the SurfaceItem
for things such as software cursors and drag-and-drop additional icons.
One of the responsibilities of the Item is to schedule repaints as needed.
Ideally, there shouldn't be any addRepaint() calls in the core code. The
Item class schedules repaints on geometry updates. In the future, it also
has to request an update if its opacity or visibility changes.
This makes the logic that determines when Xwayland windows can be marked
as ready for painting more robust.
At the moment, we call setReadyForPainting() when the surface is damaged,
but we want Toplevel stop managing damages.
Put together the two methods about window properties and rules
into the same class, since they are tightly related and they seem
a bit out of place within RuleBookModel
Small refactor patch. No behavior changes
With the new interface, the compositor sends raw image data instead of
encoding it as a png image, which causes a lot of overhead on Wayland.
In addition to that, the new interface is more extensible, for example
we can add new options or change the written image data format, however
the latter is less likely to happen.
BUG: 433776
At the moment, the session code is far from being extensible. If we
decide to add support for libseatd, it will be a challenging task with
the current design of session management code. The goal of this
refactoring is to fix that.
Another motivation behind this change is to prepare session related code
for upstreaming to kwayland-server where it belongs.
When rules configuration is invoked from window `Alt+F3` menu,
we call a custom binary `kwin_rules_dialog` which currently provides
only the rule edition dialog by embedding `RulesEditor.qml` within a
QQuickView.
This MR changes that behavior to call the full KCM from the menu.
The code to match previous rules, or compose a new one based on window
properties has been ported to the KCM from the dialog, so the overall
interaction is similar.
It has several advantages:
- uses only one entry-point to the code
- adds discoverability to the full KCM (I guess many users know how to
create a rule, but not where to delete it later)
And a drawback:
- only one instance of the KCM can be called at a time, so it will show an
error when calling it from two different windows, or if the KCM is open
in System Settings
This drawback can be solved after adding argument passing via dBus in KCM
infraestructure.
BUG: 433837
CCBUG: 417923
This reverts commit ee54fa7898.
Unfortunately, this is not a totally correct fix. If there's no pointer,
we need to announce the wl_pointer capability anyway so clients that do
not support tablet input devices can still receive emulated pointer
events.
Otherwise drmModeAtomicCommit() in DrmOutput::doAtomicCommit() fails due
to unmatched buffer sizes.
While rendering continues working properly, this makes drm freak out and
try to go back to a previous state (see the test commit in
presentAtomically()) that in turn starts issuing screen events to every
process even though it's just to say the same thing. The fact that this
happens per frame makes the system unusable as soon as fullscreen starts
happening on a scaled display.
Another thing we could do is get EglGbmBackend::scanout() to take care
of the resizing.
Our wayland interface lifespan only needs to live as long as the window
is mapped.
Given this corresponds directly to the lifespan of AbstractClient we can
just set a parent and everything is handled implicitly.
Prevent KWin from synchronously autostarting kactivitymanagerd. Indeed,
kactivitymanagerd being a QApplication it will depend on KWin
startup... this is unsatisfactory dependency wise, and it turns out
that it leads to a deadlock in the Wayland case
We're now sharing most of the X11Client activity behavior accross all
clients. This allows to cleanup some of the existing virtuals and remove
quite a bit of code overalls.
Has to introduce an extra platform specific hook since X11Client
serializes the activity information in an atom and we will probably need
to do something similar on the Wayland platform at some point.
This allows us to start interacting with the activities with kwin
wayland. They are not restored properly accross sessions though since
nothing is really persisted and the session management still seems to
be amiss.
The Script class has a DBus API we want to export. At some point this
has got broken and the run method is not exported.
It's a bit messy with script subclasses also having other invokables
that we want to export to scripts, so an adaptor is used to keep things
separated.
The interface name has technically changed, but KWin was doing something
weird and using the same interface names for the manager. Fortunately
calling Plasma code doesn't specify an interface so this still works.
On Wayland, when the compositor sends a screenshot to the requesting
app, it encodes the screenshot as a PNG image and sends the encoded data
over the pipe. The requesting app (Spectacle) then needs to decode the
data.
The issue is that encoding PNG images is not cheap. This is the main
reason why Spectacle is shown with a huge delay after you press the
PrtScr key.
In order to fix the latency issue, we need to transfer raw image data.
Unfortunately, the current dbus api of the screenshot is too cluttered
and the best option at the moment is to start with a clean slate.
This change prepares the screenshot effect for versioned dbus interface.
Most of existing dbus logic was moved out in a separate class. In order
to schedule screen shots, the screenshot effect got some new API.
QFuture<QImage> scheduleScreenShot(window, flags)
QFuture<QImage> scheduleScreenShot(area, flags)
QFuture<QImage> scheduleScreenShot(screen, flags)
If a dbus interface needs to take a screenshot, it needs to call one of
the overloaded scheduleScreenShot() functions. Every overload returns a
QFuture object that can be used for querying the result.
This change also introduces "sink" and "source" objects in the dbus api
implementation to simplify handling of QFuture objects.
Note that the QFutureInterface is undocumented, so if you use it, you do
it on your own risk. However, since Qt 5.15 is frozen for non-commercial
use and some other Plasma projects already use QFutureInterface, this
is not a big concern. For what it's worth, in Qt 6, there's the QPromise
class, which is equivalent to the QFutureInterface class.
CCBUG: 433776
CCBUG: 430869
This provides the compositor a way to indicate what output is being
rendered. The effects such as the screenshot can check the provided
screen object in order to function as expected.
If the file descriptor of the DRM device is greater than FD_SETSIZE, the
stack will be corrupted. However, it is highly unlikely that we ever hit
this case because DRM devices are opened at startup of kwin, so the file
descriptors should small.
In order to prevent the potential stack corruption, this change replaces
the usage of select() with poll().
Unlike select(), the api of poll() is much more sensible. Back 20 or so
years ago the main argument against poll() was that it's not implemented
by all platforms. But, nowadays, it's supported on all major platforms.
This is a minor regression that was introduced with the refactoring of
Toplevel::opacity().
Previously, neither X11Client nor Unmanaged had to explicitly initialize
the opacity because it was queried from the net info object in
Toplevel::opacity().
With the refactored version, X11-specific opacity code was removed from
the Toplevel class. When starting to manage a window, the opacity must
be explicitly initialized.
BUG: 432744
-listen <fd> option is deprecated in favor of the -listenfd option. This
change makes kwin query whether Xwayland supports the -listenfd option
at build time. If the pkg-config file is missing, we'll use the old listen
option.
Some old platforms don't have atomic integer supports for 64-bit wise
integer.
As indicated in GPUVis:
// Erase all knowledge of this ctx so it can be reused
We can reuse numbers after end_ctx, so with we should be fine with
32-bit integer.
Let's use a 32 bit integer for context.
bind(2) expects its second parameters is a "const struct sockaddr*",
let's cast the "struct sockaddr_un*" to "struct sockaddr*" before
passing into bind(2).
SUN_LEN is a BSD extension that also implemented by GNU, let's define
_DEFAULT_SOURCE before including "sys/un.h".
When the monitor is created, the surface may already have child
sub-surfaces. The childSubSurfaceAdded signal won't be emitted for them,
we need to handle this case explicitly.
BUG: 433511
FIXED-IN: 5.21.2
In QJSEngine, QRect is an Object, which is correct. This means that we
cannot use simple assignment operator to copy geometries, we need to use
standard ways to copy Objects, such as Object.assign() or the spread
operator, which is not available in QJSEngine yet.
Summary:
QScriptEngine is deprecated for years and suffers bitrot.
Plasma hit one super major bug with it in 5.11.0 and has now ported
away.
Main porting notes:
- creating low level functions no longer exists
The old global functions are exposed on the ScriptedEffect instance
and then the QJSValue wrappers of the globalObject are modified to
trampoline the methods at a wrapper level.
- We can then use QJSEngine to automatically do argument error checking
rather than unmarshalling a QJSValue manually which significantly
reduces a lot of code.
- We can't make FPX2 a native type, so these are QJSValue args and
unboxed there.
Long term I want overloads for animate that take int/QSize/QPoint which
are native JS types, but that might be an API break.
Test Plan:
Hopefully comprehensive unit test which passes
Tested fade/fadeDesktop manually.
It's a very invasive change, so I expect some things will be broke
please help test any JS effects.
Reviewers: #kwin, mart, fvogt
Subscribers: fvogt, zzag, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14536
Otherwise if powerdevil for example is configured to turn screen off on
the power key press, we will turn it right back on when we get key
release event.
Suggested-by: David Edmundson <kde@davidedmundson.co.uk>
Currently, the wobbly windows effect assumes that the window data will
be updated on every repaint. However, there are legit cases when the
time diff between frames can be 0, for example when per screen rendering
is on.
If we are unlucky enough and the geometry of the window changes in that
very short moment, the mapping between window quads and the bezier
patch will be wrong. The window will most likely bounce back and forth.
In order to improve handling of that tricky case, this change makes the
computeBezierPoint() function take the "uv" coordinates rather than the
absolute "xy" coordinates of window vertices. This loosens the
connection between the real geometry of the window and the cached bezier
patch, and overall makes the effect's timing code more robust.
This can be also useful if the wobbly windows effect starts accumulating
time diffs and performing the integration step every N msecs with the
purpose of maintaining uniform "wobbliness" across different refresh rates.
BUG: 433187
There are a couple of reasons not to use the lambda:
* It is unnecessary. The DrmGpu has the DRM file descriptor
* If a crash occurs somewhere in the lambda, the backtrace will be hard
to read
* Instead of processing events in the destructor of the DrmBackend
class, we should keep dispatching events without involving
QCoreApplication::processEvents() until all page flips are completed.
There seems to be an interval between when you copy something from a Wayland
client and when you attempt to paste it into an X client where m_chunks.first().first
is empty, and trying to access its .data() will cause an assertion. While we can't
really gracefully handle this situation, we can at least terminate the function early
and turn the paste operation into a noop instead of a crash.
I just had that crash, this is what coredumpctl suggested it was
happening.
We don't need to make sure we're in dmabuf mode to remove the buffer.
Worst case scenario it won't remove anything. Check the spa_data before
querying in case it's null.
qEnvironmentVariableIntValue() will return 0 if the specified variable
is not set.
This means that swap events will be disabled on AMD GPUs unless the env
var is set explicitly to 1.
This is in a way working around bad protocol, input-method-unstable-v1
and also input-method-unstable-v2 does not have a way for input-method
to mark itself as "deactivated". This can happen when e.g. user closes
the virtual keyboard using swiping down or "close keyboard" button in
keyboard.
When this happens, the state between compositor, text_input and
input_method gets out of sync, compositor does not know that input
method got deactivated and hence it will continue sending various events
to it. The quick way around it is to change focus, which makes
compositor send deactivate request to input-method, that puts compositor
and input-method in sync again.
This patch aims to solve this by tracking the last state of input
method, If we know that input method is active and text input sends us
the show event, we toggle the input-method.
I will re-iterate that this is in no way proper solution, ideally
input-method-unstable-v3 or input-method-unstable-v2 even (since it is
not upstream anyway) gains the new request which essentially allows
input-method to sync enabled/disabled state with compositor.
The contents of the if branch is identical to the implementation of the
Toplevel::damageNotifyEvent() function and setReadyForPainting() will
never be called because m_syncRequest.isPending can be true only if the
window supports sync counters.
In case the compositor wants to cancel a touch sequence, we need to
ignore subsequent touch motion and touch up events until a new sequence
is initiated by the user.
Previously, it was implicitly handled by clearing the mapping table
between the touch slots and touch ids generated by kwayland-server.
At the moment, the display name might change between Xwayland restarts.
It is a problem because the session process (plasma) may have an
outdated value of the DISPLAY environment variable after a restart.
With this change, it is guaranteed that the DISPLAY and the Xauthority
file stay the same until the server is stopped explicitly.
Since QWindowSystemInterface::handleScreenRemoved would not be called in Integration::handleScreenDisabled, Qt apps would still reference disabled screens resulting in crashes.
Previously the text values were updated to the model after
`onEditingFinished()`, that is after losing focus, to prevent
erroneus updates.
This was making also the `needsSaving` signal fire only after
a focus change, which is not consistent with the behavior of
other KCMs.
Use `onTextEdit()` instead, so the model is updated as the user
types.
BUG: 431211
Currently the highlight is only for the items. KCModuleData will come in another MR.
This is more simple implementation than the one I previously made.
Some default value are hardcoded in the KCM such as Rows count (2) and the number
of virtual desktop, on revert to default, it keeps only the first one.
Since kwin runs as a normal user, it cannot create the X11 connection
socket directory because any user process can easily compromise the
security of the system by unsetting the sticky bit.
In order to guarantee the security of the system, the socket directory
must be created by root and have the sticky bit on.
This adds a command line tool which allows the user to set the window
decoration, and then that tool is used in the two knsrc files to allow
the user to switch window decoration directly from either a KNS dialog,
or from Discover.
Xwayland starts listening to -listenfd file descriptors after the WM_S0
selection is claimed. At the moment, it is claimed asynchronously by
kwin. First, we create a dummy window and change one of its properties
to get the timestamp. After the timestamp has been received, we actually
call xcb_set_selection_owner().
This provides kwin greater control over how X11 sockets are created for
Xwayland. For example, it can be used to ensure that the DISPLAY remains
the same across Xwayland server restarts or launching Xwayland on
demand.
Even though -listen <fd> option is deprecated, we still pass it because
older versions of Xwayland may not have the -listenfd option.
This renames updateXauthorityFile to writeXauthorityEntries as it doesn't
actually update (i.e. change) anything, it just writes new ones.
Error handling is introduced, to avoid that it continues silently without
entries, which would cause all connections to fail.
Once in a while, we receive complaints from other fellow KDE developers
about the file organization of kwin. This change addresses some of those
complaints by moving all of source code in a separate directory, src/,
thus making the project structure more traditional. Things such as tests
are kept in their own toplevel directories.
This change may wreak havoc on merge requests that add new files to kwin,
but if a patch modifies an already existing file, git should be smart
enough to figure out that the file has been relocated.
We may potentially split the src/ directory further to make navigating
the source code easier, but hopefully this is good enough already.