@ -2070,57 +2070,6 @@ public:
}
} ;
static SeatInterface * findSeat ( )
{
auto server = waylandServer ( ) ;
if ( ! server ) {
return nullptr ;
}
return server - > seat ( ) ;
}
class SurfaceCursor : public Cursor
{
public :
explicit SurfaceCursor ( TabletToolV2Interface * tool )
: Cursor ( )
{
setParent ( tool ) ;
connect ( tool , & TabletToolV2Interface : : cursorChanged , this , [ this ] ( const TabletCursorSourceV2 & cursor ) {
if ( auto surfaceCursor = std : : get_if < TabletSurfaceCursorV2 * > ( & cursor ) ) {
// If the cursor is unset, fallback to the cross cursor.
if ( ( * surfaceCursor ) & & ( * surfaceCursor ) - > enteredSerial ( ) ) {
if ( ! m_surfaceSource ) {
m_surfaceSource = std : : make_unique < SurfaceCursorSource > ( ) ;
}
m_surfaceSource - > update ( ( * surfaceCursor ) - > surface ( ) , ( * surfaceCursor ) - > hotspot ( ) ) ;
setSource ( m_surfaceSource . get ( ) ) ;
return ;
}
}
QByteArray shape ;
if ( auto shapeCursor = std : : get_if < QByteArray > ( & cursor ) ) {
shape = * shapeCursor ;
} else {
shape = QByteArrayLiteral ( " cross " ) ;
}
static WaylandCursorImage defaultCursor ;
if ( ! m_shapeSource ) {
m_shapeSource = std : : make_unique < ShapeCursorSource > ( ) ;
}
m_shapeSource - > setTheme ( defaultCursor . theme ( ) ) ;
m_shapeSource - > setShape ( shape ) ;
setSource ( m_shapeSource . get ( ) ) ;
} ) ;
}
private :
std : : unique_ptr < ShapeCursorSource > m_shapeSource ;
std : : unique_ptr < SurfaceCursorSource > m_surfaceSource ;
} ;
/**
* Handles input coming from a tablet device ( e . g . wacom ) often with a pen
*/
@ -2130,172 +2079,6 @@ public:
TabletInputFilter ( )
: InputEventFilter ( InputFilterOrder : : Tablet )
{
const auto devices = input ( ) - > devices ( ) ;
for ( InputDevice * device : devices ) {
integrateDevice ( device ) ;
}
connect ( input ( ) , & InputRedirection : : deviceAdded , this , & TabletInputFilter : : integrateDevice ) ;
connect ( input ( ) , & InputRedirection : : deviceRemoved , this , & TabletInputFilter : : removeDevice ) ;
auto tabletNextOutput = new QAction ( this ) ;
tabletNextOutput - > setProperty ( " componentName " , QStringLiteral ( " kwin " ) ) ;
tabletNextOutput - > setText ( i18n ( " Move the tablet to the next output " ) ) ;
tabletNextOutput - > setObjectName ( QStringLiteral ( " Move Tablet to Next Output " ) ) ;
KGlobalAccel : : setGlobalShortcut ( tabletNextOutput , QList < QKeySequence > ( ) ) ;
connect ( tabletNextOutput , & QAction : : triggered , this , & TabletInputFilter : : trackNextOutput ) ;
}
static TabletSeatV2Interface * findTabletSeat ( )
{
auto server = waylandServer ( ) ;
if ( ! server ) {
return nullptr ;
}
TabletManagerV2Interface * manager = server - > tabletManagerV2 ( ) ;
return manager - > seat ( findSeat ( ) ) ;
}
void integrateDevice ( InputDevice * inputDevice )
{
auto device = qobject_cast < LibInput : : Device * > ( inputDevice ) ;
if ( ! device | | ( ! device - > isTabletTool ( ) & & ! device - > isTabletPad ( ) ) ) {
return ;
}
TabletSeatV2Interface * tabletSeat = findTabletSeat ( ) ;
if ( ! tabletSeat ) {
qCCritical ( KWIN_CORE ) < < " Could not find tablet seat " ;
return ;
}
struct udev_device * const udev_device = libinput_device_get_udev_device ( device - > device ( ) ) ;
const char * devnode = udev_device_get_syspath ( udev_device ) ;
auto deviceGroup = libinput_device_get_device_group ( device - > device ( ) ) ;
auto tablet = static_cast < TabletV2Interface * > ( libinput_device_group_get_user_data ( deviceGroup ) ) ;
if ( ! tablet ) {
tablet = tabletSeat - > addTablet ( device - > vendor ( ) , device - > product ( ) , device - > sysName ( ) , device - > name ( ) , { QString : : fromUtf8 ( devnode ) } ) ;
libinput_device_group_set_user_data ( deviceGroup , tablet ) ;
}
if ( device - > isTabletPad ( ) ) {
const int buttonsCount = libinput_device_tablet_pad_get_num_buttons ( device - > device ( ) ) ;
const int ringsCount = libinput_device_tablet_pad_get_num_rings ( device - > device ( ) ) ;
const int stripsCount = libinput_device_tablet_pad_get_num_strips ( device - > device ( ) ) ;
const int modes = libinput_device_tablet_pad_get_num_mode_groups ( device - > device ( ) ) ;
auto firstGroup = libinput_device_tablet_pad_get_mode_group ( device - > device ( ) , 0 ) ;
tabletSeat - > addTabletPad ( device - > sysName ( ) , device - > name ( ) , { QString : : fromUtf8 ( devnode ) } , buttonsCount , ringsCount , stripsCount , modes , libinput_tablet_pad_mode_group_get_mode ( firstGroup ) , tablet ) ;
}
}
static void trackNextOutput ( )
{
const auto outputs = workspace ( ) - > outputs ( ) ;
if ( outputs . isEmpty ( ) ) {
return ;
}
int tabletToolCount = 0 ;
InputDevice * changedDevice = nullptr ;
const auto devices = input ( ) - > devices ( ) ;
for ( const auto device : devices ) {
if ( ! device - > isTabletTool ( ) ) {
continue ;
}
tabletToolCount + + ;
if ( device - > outputName ( ) . isEmpty ( ) ) {
device - > setOutputName ( outputs . constFirst ( ) - > name ( ) ) ;
changedDevice = device ;
continue ;
}
auto it = std : : find_if ( outputs . begin ( ) , outputs . end ( ) , [ device ] ( const auto & output ) {
return output - > name ( ) = = device - > outputName ( ) ;
} ) ;
+ + it ;
auto nextOutput = it = = outputs . end ( ) ? outputs . first ( ) : * it ;
device - > setOutputName ( nextOutput - > name ( ) ) ;
changedDevice = device ;
}
const QString message = tabletToolCount = = 1 ? i18n ( " Tablet moved to %1 " , changedDevice - > outputName ( ) ) : i18n ( " Tablets switched outputs " ) ;
OSD : : show ( message , QStringLiteral ( " input-tablet " ) , 5000 ) ;
}
void removeDevice ( InputDevice * inputDevice )
{
auto device = qobject_cast < LibInput : : Device * > ( inputDevice ) ;
if ( device ) {
auto deviceGroup = libinput_device_get_device_group ( device - > device ( ) ) ;
libinput_device_group_set_user_data ( deviceGroup , nullptr ) ;
TabletSeatV2Interface * tabletSeat = findTabletSeat ( ) ;
if ( tabletSeat ) {
tabletSeat - > removeDevice ( device - > sysName ( ) ) ;
} else {
qCCritical ( KWIN_CORE ) < < " Could not find tablet to remove " < < device - > sysName ( ) ;
}
}
}
TabletToolV2Interface : : Type getType ( const TabletToolId & tabletToolId )
{
using Type = TabletToolV2Interface : : Type ;
switch ( tabletToolId . m_toolType ) {
case InputRedirection : : Pen :
return Type : : Pen ;
case InputRedirection : : Eraser :
return Type : : Eraser ;
case InputRedirection : : Brush :
return Type : : Brush ;
case InputRedirection : : Pencil :
return Type : : Pencil ;
case InputRedirection : : Airbrush :
return Type : : Airbrush ;
case InputRedirection : : Finger :
return Type : : Finger ;
case InputRedirection : : Mouse :
return Type : : Mouse ;
case InputRedirection : : Lens :
return Type : : Lens ;
case InputRedirection : : Totem :
return Type : : Totem ;
}
return Type : : Pen ;
}
TabletToolV2Interface * createTool ( const TabletToolId & tabletToolId )
{
TabletSeatV2Interface * tabletSeat = findTabletSeat ( ) ;
const auto f = [ ] ( InputRedirection : : Capability cap ) {
switch ( cap ) {
case InputRedirection : : Tilt :
return TabletToolV2Interface : : Tilt ;
case InputRedirection : : Pressure :
return TabletToolV2Interface : : Pressure ;
case InputRedirection : : Distance :
return TabletToolV2Interface : : Distance ;
case InputRedirection : : Rotation :
return TabletToolV2Interface : : Rotation ;
case InputRedirection : : Slider :
return TabletToolV2Interface : : Slider ;
case InputRedirection : : Wheel :
return TabletToolV2Interface : : Wheel ;
}
return TabletToolV2Interface : : Wheel ;
} ;
QList < TabletToolV2Interface : : Capability > ifaceCapabilities ;
ifaceCapabilities . resize ( tabletToolId . m_capabilities . size ( ) ) ;
std : : transform ( tabletToolId . m_capabilities . constBegin ( ) , tabletToolId . m_capabilities . constEnd ( ) , ifaceCapabilities . begin ( ) , f ) ;
TabletToolV2Interface * tool = tabletSeat - > addTool ( getType ( tabletToolId ) , tabletToolId . m_serialId , tabletToolId . m_uniqueId , ifaceCapabilities , tabletToolId . deviceSysName ) ;
const auto cursor = new SurfaceCursor ( tool ) ;
Cursors : : self ( ) - > addCursor ( cursor ) ;
m_cursorByTool [ tool ] = cursor ;
return tool ;
}
bool tabletToolEvent ( TabletEvent * event ) override
@ -2304,25 +2087,7 @@ public:
return false ;
}
TabletSeatV2Interface * tabletSeat = findTabletSeat ( ) ;
if ( ! tabletSeat ) {
qCCritical ( KWIN_CORE ) < < " Could not find tablet manager " ;
return false ;
}
auto tool = tabletSeat - > toolByHardwareSerial ( event - > tabletId ( ) . m_serialId , getType ( event - > tabletId ( ) ) ) ;
if ( ! tool ) {
tool = createTool ( event - > tabletId ( ) ) ;
}
switch ( event - > type ( ) ) {
case QEvent : : TabletEnterProximity :
case QEvent : : TabletPress :
case QEvent : : TabletMove :
m_cursorByTool [ tool ] - > setPos ( event - > globalPosition ( ) ) ;
break ;
default :
break ;
}
TabletToolV2Interface * tool = input ( ) - > tablet ( ) - > ensureTabletTool ( event - > tabletId ( ) ) ;
// NOTE: tablet will be nullptr as the device is removed (see ::removeDevice) but events from the tool
// may still happen (e.g. Release or ProximityOut events)
@ -2415,11 +2180,7 @@ public:
bool tabletToolButtonEvent ( uint button , bool pressed , const TabletToolId & tabletToolId , std : : chrono : : microseconds time ) override
{
TabletSeatV2Interface * tabletSeat = findTabletSeat ( ) ;
auto tool = tabletSeat - > toolByHardwareSerial ( tabletToolId . m_serialId , getType ( tabletToolId ) ) ;
if ( ! tool ) {
tool = createTool ( tabletToolId ) ;
}
TabletToolV2Interface * tool = input ( ) - > tablet ( ) - > ensureTabletTool ( tabletToolId ) ;
if ( ! tool - > isClientSupported ( ) ) {
return false ;
}
@ -2430,7 +2191,7 @@ public:
TabletPadV2Interface * findAndAdoptPad ( const TabletPadId & tabletPadId ) const
{
Window * window = workspace ( ) - > activeWindow ( ) ;
auto seat = findTabletSeat ( ) ;
TabletSeatV2Interface * seat = waylandServer ( ) - > tabletManagerV2 ( ) - > seat ( waylandServer ( ) - > seat ( ) ) ;
if ( ! window | | ! window - > surface ( ) | | ! seat - > isClientSupported ( window - > surface ( ) - > client ( ) ) ) {
return nullptr ;
}
@ -2492,8 +2253,6 @@ public:
strip - > sendFrame ( std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( time ) . count ( ) ) ;
return true ;
}
QHash < TabletToolV2Interface * , Cursor * > m_cursorByTool ;
} ;
static AbstractDropHandler * dropHandler ( Window * window )