Similar to the change regarding pointer and touch a
KeyboardInputRedirection is created. The Xkb class is also moved to
the new files keyboard_input.h and keyboard_input.cpp.
Just like in the case of PointerInputRedirection no signals are added,
but the existing signals in InputRedirection are directly invoked.
All pointer related code is moved into a new class called
PointerInputRedirection.
The main idea is to simplify the code and make it easier to maintain.
Therefore also a few changes in the setup were performed:
* before init() is called, no processing is performed
* init() is only called on Wayland and after Workspace is created
* init property is set to false once Workspace or WaylandServer is
destroyed
Thus code can operate on the following assumptions:
* Workspace is valid
* WaylandServer is valid
* ScreenLocker integration is used
The various checks whether there is a waylandServer() and whether
there is a seat are no longer needed.
Some of the checks have been reordered to be faster in the most common
use case of using libinput. E.g. whether warping is supported is first
evaluated by the variable bound to whether we have libinput and only if
that is false the backend is checked.
The new class doesn't have signals but invokes the signals provided
by InputRedirection. I didn't want to add new signals as I consider
them as not needed. The areas in KWin needing those signals should
be ported to InputEventFilters.
So far the area based edges connected directly to global pointer pos
changed in InputRedirection. This didn't allow proper checking whether
the edge was triggered (e.g. missing timestamp).
This change merges the functionality into the new input filter mechanism.
There is now a dedicated input filter for screen edges, installed after
lock screen and before effects. It always passes events on, but also passes
all events through ScreenEdges to handle the activation. As it's installed
after the lock screen filter we don't need to check for screen locked any
more.
The code is now similar strucutured to the existing X11 based variants
and maybe will allow to also merge the X11 variant with the new one.
The logic should not be tied to whether libinput is used. It's relevant
for all Wayland backends whether they use libinput or not.
In addition this should generate a pointer motion event, so that proper
processing can take place and we get proper pointer enter events.
If the pointer is warped the position change should be treated like
a change coming from the input device. Our normal processing should
take place.
A problem in this case is the timestamp to pass to the wayland server.
Normally our timestamps come from the backend/libinput and we don't
know the next one. As an intermediate solution we just use the last
timestamp on the seat. In future a solution could be to not use the
backend's timestamp at all, but have our own timestamp handling.
When the screen gets locked any existing sequence gets cancelled
and the focused touch surface gets reset. While screen is locked
touch events are filtered to only go to lock screen or input methods.
Test case is added for touch event during lock screen.
Reviewed-By: Bhushan Shah
Instead of only making the active client the focused keyboard surface,
the method now also performs the lock screen security restriction.
Also just like udatePointerWindow the method becomes public, so that
it can be used from the LockScreenEventFilter and is connected for
lock state changes. This means as soon as the screen locks the current
focused keyboard surface will get a leave event and get an enter event
once the screen unlocks.
The auto test is adjusted to verify these new conditions.
Reviewed-By: Bhushan Shah
InputRedirection connects to lockStateChanged to udate the current
pointer window. This way we can ensure that the current pointer
surface gets reset as soon as the screen locks (c.f. the expect
fail in the autotest) and also that it restores to the surface under
the mouse once the screen is unlocked.
The relevant code was not yet lock screen aware and performed an
early exit. Part of the code was fine, e.g. findToplevel is lock
screen aware. So this change adjusts the methods for updating the
internal window and decoration to be lock screen aware, that is they
get reset. With that updatePointerWindow is also lock screen aware.
Thus the LockScreenFilter can also use updatePointerWindow just like
the normal handling and does not need to reimplement parts of it. As
it now relies on other code being correct it has an additional check
to verify that the current pointer surface is a surface which is allowed
to get events. If it isn't the events are not forwarded.
Reviewed-By: Bhushan Shah
The main motivation of this change is to remove the spaghetti code
in the input event handling. Each area of processing (e.g. lock screen)
is moved into a dedicated event filter. Processing the events now just
means calling a virtual method on each of the filters. As soon as the
method returns true, the processing is stopped.
This allows to have the security for the lock screen just in one place:
whenever the screen is locked the event filter can ensure that the events
are not further processed.
Currently all event filters are implemented directly in input.cpp and
are registered by InputRedirection itself. In future it would be better
to have those moved to the area they belong to and get registered from
there. E.g. the input filter for EffectsHandlerImpl should be created
by EffectsHandlerImpl. This requires an improved API to ensure that the
filters are installed in the correct sequence.
If the screen is locked and no lock screen is shown yet we unset
the focused keyboard surface on key event. Similar we restore when
screen is unlocked.
This should hopefully fix the broken lockscreen unit test which hits
the special condition as the greeter doesn't show up on build.kde.org.
InputRedirection uses the inputTransformation() to pass to SeatInterface
for focused pointer surface. This prepares for proper input
transformation including scaling and rotation.
The implementation of VirtualTerminal is too linux specific and doesn't
compile on e.g. freebsd. Currently the most usage is in combination with
libinput. Only usage is:
* libinput related functionality in InputRedirection
* backends without custom input handling
Thus binding the feature to whether libinput is available is currently
the least invasive approach to get it compile on non-Linux.
In the long run this needs a different solution. The functionality
provided by VirtualTerminal is required and without the backends don't
work. It's needed to get notified about VT switches, when KWin needs to
stop rendering. So a solution for non-Linux needs to be found if
non-Linux wants to provide Wayland in future.
REVIEW: 126182
We need to update the pointer position, also if the screen is locked.
Otherwise the pointer doesn't move on the locked screen with libinput.
In addition we need to use the m_globalPointer for finding the correct
lock screen window as updatePointerWindow also does sanity checking on
the coordinates.
Also we need to introduce security checks where we use the signal.
REVIEW: 126103
When screen is locked,
- No window other then screenlocker or inputmethods gets rendered
- Only screenlocker gets keyboard events
- Only screenlocker and inputmethods get mouse events
Things that are not secured/tested are :
- Touch events
- Global shortcuts for screenlocker
- Fallback/emergency screen not yet working
REVIEW: 126015
The way it was implemented it allowed an X11 unmanaged window to become
a key logger. Basically as soon as there was an unmanaged window it got
all key events. This problem was discovered through the xembed-sni-proxy
which broke key input to all Wayland windows in a Plasma/Wayland session.
With this change Unmanaged windows don't get any key events at all. This
might break some applications as e.g. context menus are using override
redirect windows. A test with Qt applications shows that the menus are
still functional and the events are delivered correctly internally.
If applications show problems with this change, we might need to weaken
the restriction.
The Connection thread fills the event queue, it gets read from the
main thread. In order to properly support the threaded approach the
setup is changed to delegate into the own thread.
Properly handle the mouse press/release events in InputRedirection
while we move windows. If it's the last mouse release event we end
the move resize of the window. For that we reuse the code written
in Client.
We take the configuration from the kcminputrc config file, group
keyboard (see plasma-desktop.git/kcms/keyboard/kcmmisc.cpp)
The values are only used for libinput. For backends providing input
events we expect to get repeated key events anyway.
On popular demand!
This change tracks how modifiers are used and detects a modifier only
key press/release. That is:
* no other key is pressed when the modifier gets pressed
* no other key gets pressed before the modifier gets released
If such a press/release is detected, we call a configurable dbus call.
The possible shortcuts can be configured in kwinrc, group
"ModifierOnlyShortcuts". The following keys are supported:
* Shift
* Control
* Alt
* Meta
As value it takes a QStringList (comma seperated string) with
service,path,interface,method,additionalargs
E.g. to invoke Desktop Grid effect on Meta key:
[ModifierOnlyShortcuts]
Meta=org.kde.kglobalaccel,/component/kwin/,org.kde.kglobalaccel.Component,invokeShortcut,ShowDesktopGrid
I do not intend to add a config interface for it. Let's keep it a hidden
way.
REVIEW: 124954
A click outside a popup should close the popup and not be passed to the
window at the pointer position. Thus we only update the internal pointer
window if the internal pointer window does not represent a visible
popup.
* Need to pass modifiers to Client::keyPressEvent
* Need to check whether move/resize ended before updating position,
otherwise it keeps stuck in move/resize after ending
So far if the new position fell outside of the screen, we ignored
the movement completely. This change only discards the event if both
x and y coordinates are outside the screen. If one component is still
on the screen it will be used. So a movement to top-left on left border
will result in a pointer movement towards top.
The KGlobalAccelD which gets created by KWin needs a plugin for the
platform specific parts. This change introduces such a plugin. It's
linked against kwin so that it can integrate with the core.
On enable the plugin registers itself in the InputRedirection and
GlobalShortcutsManager checks the plugin whether a shortcut got
triggered.
As the loading of the plugin must happen after InputRedirection is
fully created a dedicated init method is added to InputRedirection.
REVIEW: 124187
Toplevel provides the input shape forwarded from SurfaceInterface. The
shape is evaluated in InputRedirection when finding the Toplevel at a
given position.
We used to change it only on keypresses. This resulted in the strange
situation that e.g. the input method virtual keyboard doesn't show up
until one presses a real key, because e.g. maliit only activates the
keyboard if there is an active focus object in the Qt application.
If there is a visible internal window it gets the pointer events.
The assumption is that the last created internal window is the top
most in stacking order.
So far input events were sent through Xwayland which is not needed as
we have all information available. Even more it had the pointer surface
on the wrong window when interacting with decorations as it was on the
window and not on the decoration.
When creating a new xkb keymap we need to pass it to the Wayland server's
seat. As the Wayland protocol expects the keymap as a file descriptor, a
temporary file is created, mmapped and the keymap written into it. As
the Wayland protocol doesn't restrict how long the file descriptor needs
to be valid we keep any created temporary file around till the
InputRedirection gets destroyed.
This change is motivated by the fact that we need to suspend libinput
before switching the virtual terminal. Also we don't want to take over
libinput if we do not have a VirtualTerminal created - in windowed mode
we don't want libinput to be started. So binding it to the backends which
create the VirtualTerminal makes sense.
The KWin::Application gains a new signal virtualTerminalCreated which is
emitted from VirtualTerminal once it's properly setup. This is used by
Input to create Libinput integration instead of binding it to logind.
Furthermore Libinput gets suspended when the VirtualTerminal reports that
it is no longer active. For re-activation we still just use logind's
session active property.
When our session gets inactive libinput loses all devices, thus our
Seat would not have neither keyboard, pointer nor touch. To not confuse
all connected clients we block updates while libinput is suspended. After
resume we check whether something actually changed and emit the
corresponding signals to ensure everything is up to date.
We handle device added/remove to monitor whether we have keyboard,
pointer and touch devices and emit signals. Those are used to update
the SeatInferface from InputRedirection.
InputRedirection gains basic support for processing touch events which
are delegated to KWayland::Server.
WaylandBackend accepts touch events from KWayland::Client and delegates
them to the InputRedirection.
The AbstractBackend registers itself in the WaylandServer allowing
external users to easily get to the backend and not needing to test
manually which backend is used.
This new backend allows to start a kwin_wayland server nested on an
X-Server by using a normal X11 window as output. This allows testing
kwin_wayland without needing to start another Wayland server first.
The behavior is triggered by using new command line arguments:
--windowed
--x11-display=<:0>
With optional --width and --height arguments.
In this mode the WaylandBackend is not created at all.
So far the backend is not fully integrated yet and only the QPainter
backend supports this mode.
This replaces getting the Cursor through the X11CursorTracker which
is now completely dropped. The Cursor data is now passed through from
the Wayland server and forwared to the WaylandBackend.
Pointer events are no longer sent through the methods on Toplevel,
but properly sent through the SeatInterface. This has the advantage
that SeatInterface properly tracks which is the focused pointer surface
and does not need to use the xtest extension.
KGlobalAccel sets the timestamp as a property and we need to set our
x11Time to it otherwise following keyboard grabs might fail.
Requires 61e2a156678eef033b2629f7c72530dc78d7c3ac in kglobalaccel.
We don't want the cursor to leave the visible area, so better check that
the cursor doesn't leave it. And when the screens changes better check
that the cursor is still on a visible screen. If not: put it back to the
center of the closest screen.
kwin_wayland gains a new command line option to enable libinput support.
This is needed as logind blanks the VT when the session controller
releases the control. So a nested compositor can seriously affect the
primary session. Thus it needs a dedicated command line switch to
enable it.
By default libinput support is disabled for kwin_x11 and can be enabled
for kwin_wayland in case KWin is compiled with libinput support.
With libinput we have the problem that we need to have privileges to
open the device files. In order to not need wrappers or suid bits, we
use logind. This means that kwin_wayland has to be the session controler.
A LogindIntegration is added to connect to logind and wrap the dbus
calls. This is based on the logind integration done for ksld in
ksmserver. The LogindIntegration is started by Workspace and the
InputRedirection tries to become the session controller and starts the
libinput integration only after this succeeded.
Libinput is an optional dependency for getting low level input events.
As opening the input devices requires root privs this is rather
pointless in the current state. But there is a small added test app which
can be executed with root privs to demonstrate the functionality. To
properly get input events we need a wrapper like it's used in weston.
So far the following is setup:
* opening devices found by udev
* forwarding keyboard events to InputRedirection
* forwarding pointer button events to InputRedirection
* forwarding pointer axis events to InputRedirection
* signals emitted for pointer motion events
Pointer motion events need some further work as they are provided
as delta events. We need to track that and map them properly.
Also missing are touch events due to me not having a touch screen.
It should be fairly simple to setup the touch events, though.
Also hotplugging of devices is not yet implemented.
Some systems (e.g. openSuSE) don't install the xkbcommon header into
/usr/include/xkbcommon/xkbcommon.h (which is always in the include path),
but instead into a subdirectory, which is in the openSuSE case
/usr/include/pkg/libxkbcommon/xkbcommon/xkbcommon.h. This means that e.g.
kcm_kwinrules will not compile there since it includes input.h
REVIEW: 117069
Forward all key press events to the TabBox if it is currently grabbed and
connect the TabBox to the modifiers changed signal for checking if TabBox
should be ended.
Used by Cursor to properly emit the mouseChanged signal which for
historic reasons includes the keyboard modifiers.
Again some fiddling around with the autotests and kcmrules needed to
make it compile. This needs improvement!
A new GlobalShortcutsManager is introduced which is responsible for
holding the registered shortcuts and triggering the matching action.
The InputRedirection checks with the GlobalShortcutManager whether a key
press event triggers a global shortcut and stops processing the event in
that case.
At the moment the GlobalShortcutsManager only supports the very basics
for KWin internal usage. External applications can not yet make usage of
the global shortcut system inside KWin.
When moving/resizing a window we don't want the keyboard events being
passed to the Clients. Instead we want to do the normal processing.
Unfortunately moving the window through the keyboard relies on warping
the pointer which is not (yet) available on Wayland. This means that this
is not yet working, but ending through enter/escape etc. is working as
expected.
Major new functionality is xkbcommon support. InputRedirection holds an
instance to a small wrapper class which has the xkb context, keymap and
state. The keymap is initialied from the file descriptor we get from the
Wayland backend.
InputRedirection uses this to translate the keycodes into keysymbols and
to QString and to track the modifiers as provided by the
Qt::KeybordModifiers flags.
This provides us enough information for internal usage (e.g. pass through
effects if they have "grabbed" the keyboard).
If KWin doesn't filter out the key events, it passes them on to the
currently active Client respectively an unmanaged on top of the stack.
This needs still some improvement (not each unmanaged should get the
event). The Client/Unmnaged still uses xtest extension to send the key
events to the window. So keylogging is still possible.
InputRedirection keeps track of the Toplevel which is currently the one
which should get pointer events. This is determined by checking whether
there is an Unmanaged or a Client at the pointer position. At the moment
this is still slightly incorrect, e.g. pointer grabs are ignored,
unmanaged are not checked whether they are output only and input shapes
are not yet tracked.
The pointer events are delivered to the Toplevel as:
* enter
* leave
* move
* button press
* axis event
Nevertheless move events are still generated in InputRedirection through
xcb test for simplicity. They are still send to the root window, so all
windows get mouse move.
Button press and axis are generated only in the implementations of the
event handlers and delivered directly to the window, so other windows
won't see it.
InputRedirection forwards pointer events (currently motion, press and
release) through the EffectsHandlerImpl for the case that an effect has
intercepted pointer events.
If the KWin operation mode is not X11 only, the window for intercepting
the mouse events is no longer created.
So far this new class is not yet doing much. The WaylandBackend forwards
the received pointer events to this InputRedirection class. From there
signals are emitted to inform internal areas about the changes first.
The events are currently forwarded to X through the xtest extension. This
will be removed in future. Input will be forwarded directly to the
surface which wants it (no matter whether X11 or Wayland).