On dimanche 31 janvier 2021 00:30:14 CET Fabian Vogt wrote:
> I suspect that something else is triggering keyboard layout reloads or
> similar in a loop. The keyboard kded module listens for new keyboards and
> mouse events and configures them, which is likely to be called on resume
> when devices get reenumerated. You could try to disable that before
> suspend/resume.

Well spotted. After
qdbus org.kde.kded5 /kded unloadModule keyboard
and suspend/resume, I got only one call to KGlobalAccelImpl::x11MappingNotify

This is amazing. Suddenly it manages to reconnect to wifi instantly, too,
and my global shortcuts work instantly.
Previously, kded kept everyone so busy that everything crawled for about a 
minute, and wifi timed out...
 
> If I run "xmodmap .Xmodmap" here with "xev" open, I get quite a high count
> of mapping change events, presumably for every assignment in the file. If
> the kded calls xmodmap with many assignments, that would be enough to
> explain the issue. Maybe xmodmap could be optimized to upload everything at
> once, like setxkbmap.

I debugged what happens in plasma-desktop/kcms/keyboard
and when resuming from suspend, XInputEventNotifier::processOtherEvents()
emits newKeyboardDevice() many many times.
Each time, the slot KeyboardDaemon::configureKeyboard() does all this

KeyboardConfig::load configuring layouts true configuring options true
X11Helper::getGroupNames Fetched keyboard model from X server: "pc101"
XkbHelper::runConfigLayoutCommand Executed successfully in  137 ms 
"/usr/bin/setxkbmap -layout us,fr -option -option compose:caps"
XkbHelper::runConfigLayoutCommand    and with xmodmap 137 ms
X11Helper::getGroupNames Fetched layout groups from X server:       layouts: 
("us", "fr")   variants: ("", "")
KeyboardLayoutActionCollection::loadLayoutShortcuts Skipping empty shortcut for 
"us"
KeyboardLayoutActionCollection::loadLayoutShortcuts Skipping empty shortcut for 
"fr"
KeyboardLayoutActionCollection::loadLayoutShortcuts Cleaning component 
shortcuts on load true

Going back up, the reason why processOtherEvents() thinks there's a new device 
is this:

XInputEventNotifier::getNewDeviceEventType New device id: 15
XInputEventNotifier::getNewDeviceEventType id: 2 name: Virtual core pointer 
used as: 0
XInputEventNotifier::getNewDeviceEventType id: 3 name: Virtual core keyboard 
used as: 1
XInputEventNotifier::getNewDeviceEventType id: 4 name: Virtual core XTEST 
pointer used as: 4
XInputEventNotifier::getNewDeviceEventType id: 5 name: Virtual core XTEST 
keyboard used as: 3
XInputEventNotifier::getNewDeviceEventType id: 6 name: Power Button used as: 3
XInputEventNotifier::getNewDeviceEventType id: 7 name: Video Bus used as: 3
XInputEventNotifier::getNewDeviceEventType id: 8 name: Sleep Button used as: 3
XInputEventNotifier::getNewDeviceEventType id: 9 name: Logitech Craft used as: 4
XInputEventNotifier::getNewDeviceEventType id: 10 name: Logitech MX Master 2S 
used as: 4
XInputEventNotifier::getNewDeviceEventType id: 11 name: Logitech MX Master used 
as: 4
XInputEventNotifier::getNewDeviceEventType id: 12 name: Integrated Camera: 
Integrated C used as: 3
XInputEventNotifier::getNewDeviceEventType id: 13 name: Integrated Camera: 
Integrated I used as: 3
XInputEventNotifier::getNewDeviceEventType id: 14 name: AT Translated Set 2 
keyboard used as: 3
XInputEventNotifier::getNewDeviceEventType id: 15 name: SynPS/2 Synaptics 
TouchPad used as: 4
XInputEventNotifier::getNewDeviceEventType new pointer device, id: 15 name: 
SynPS/2 Synaptics TouchPad used as: 

Before that, it got notified of new device 6, 7, 8, and so on.
It's like X is re-enabling the devices one after the other, and we react to 
each one immediately.

This misdetects the device types though:
   new keyboard device, id: 13 name: Integrated Camera: Integrated I used as: 3
No, my webcam doesn't have keys...

And for some reason, even mouse devices trigger keyboard processing, see the 
arghh comment:

bool XInputEventNotifier::processOtherEvents(xcb_generic_event_t* event)
{
    int newDeviceType = getNewDeviceEventType(event);
    if( newDeviceType == DEVICE_KEYBOARD ) {
        emit(newKeyboardDevice());
    }
    else if( newDeviceType == DEVICE_POINTER ) {
        emit(newPointerDevice());
        emit(newKeyboardDevice());  // arghhh, looks like X resets xkb map even 
when only pointer device is connected
    }
    return true;
}

> I actually had the issue that calling xmodmap here basically froze the whole
> session for a while, which was probably caused by that behaviour.
> Agreed. If those events are caused by something we can't fix, then this
> might turn out to be the best option though.

Now I'm thinking maybe the compression should happen in the keyboard module... ?
That wouldn't fix the xmodmap issue though.
Maybe we're seeing a N devices * M keys multiplication issue, i.e. it would be 
good to compress at both levels.

-- 
David Faure, fa...@kde.org, http://www.davidfaure.fr
Working on KDE Frameworks 5



Reply via email to