-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(#620) Enabling keyboard LEDs when the modifier state changes #3441
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3441 +/- ##
==========================================
- Coverage 77.45% 77.14% -0.32%
==========================================
Files 1073 1076 +3
Lines 68782 69118 +336
==========================================
+ Hits 53278 53323 +45
- Misses 15504 15795 +291 ☔ View full report in Codecov by Sentry. |
|
||
virtual void set_leds(KeyboardLeds leds) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noting that this is a platform ABI break
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change, and the ABI break are now unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think this is unnecessary here (as is the ABI break)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My first thought is that this should be more explicit.
- Keyboard devices register for modifier state updates
- Modifier updates are passed through that registrar
The only question then is whether the register is a new object or just a new interface supported by XKBMapper
(Maybe you can shoot this idea down though?)
{ | ||
the_default_input_device_hub()->for_each_mutable_input_device([&](mir::input::Device& device) | ||
{ | ||
if (device.id() == device_id) | ||
device.set_leds(leds); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably capture the_default_input_device_hub()
, not call it every time the mapping state changes.
And, surely, there could be a more direct way from XKBMapper
to the corresponding device than scanning everything registered on the device hub? (E.g. a map MirInputDeviceId
-> callback)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that the_default_input_device_hub()
also relies on the the_key_mapper()
, so it's a circular dependency. I will see if there is some other way around this, perhaps with the "registration" idea that you said earlier.
49b787c
to
b361733
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After we spoke I thought you were going to propose a solution that preserved ABI. This isn't that
src/common/input/xkb_mapper.cpp
Outdated
#include "mir/input/xkb_mapper.h" | ||
#include "mir/input/xkb_mapper_deprecated.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would we rename the file and break downstreams that use it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the tricky part is that the import will be the same when we include mir/input/xkb_mapper.h
. So one of them has to be named differently, and I chose the old one.
Would it be a better idea to rename the new one to something slightly different? Or is there a better solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I thought "we don't change old stuff, just deprecate it". New stuff can be called by new names, old stuff cannot
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why KeyMapper is being changed. Especially when there are now two different definitions
|
||
virtual void set_leds(KeyboardLeds leds) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change, and the ABI break are now unnecessary
class KeyMapperObserver | ||
{ | ||
public: | ||
virtual ~KeyMapperObserver() = default; | ||
virtual void leds_set(MirInputDeviceId id, KeyboardLeds leds) = 0; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a KeyMapper observer. It is a LED state observer.
We should be keeping the KeyMapper interface unchanged. The ObserverRegister can be part of another interface implemented by XkbMapper.
Also, wouldn't it be better to register with the device id
and only send notifications to the corresponding device. (And not notify all devices most of which drop the notification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup I agree 👍
@@ -39,6 +40,26 @@ | |||
|
|||
namespace mi = mir::input; | |||
|
|||
namespace | |||
{ | |||
class DefaultInputDeviceHubKeyMapperObserver : public mi::KeyMapperObserver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the DefaultInputDeviceHub should be registering. Only devices that support LEDs
4ac484a
to
24e5e33
Compare
class LedObserver | ||
{ | ||
public: | ||
virtual ~LedObserver() = default; | ||
virtual void leds_set(MirInputDeviceId id, KeyboardLeds leds) = 0; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is our practice to disable CopyAssign for interfaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems unfinished
class LedObserverRegistrar : public ObserverRegistrar<LedObserver> | ||
{ | ||
public: | ||
virtual ~LedObserverRegistrar() = default; | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As previously discussed I think we should be registering with a device id, which isn't supported by ObserverRegistrar<>
|
||
virtual void set_leds(KeyboardLeds leds) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think this is unnecessary here (as is the ABI break)
void register_interest(std::weak_ptr<LedObserver> const& observer) override; | ||
void register_interest( | ||
std::weak_ptr<LedObserver> const& observer, | ||
Executor& executor) override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this implemented or used?
I have updated it 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could simplify further and reduce change
include/platform/mir/input/device.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this file need to move?
include/platform/mir/input/device.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this file need to move?
std::shared_ptr<InputReport> const& report); | ||
std::shared_ptr<InputReport> const& report, | ||
std::shared_ptr<LedObserverRegistrar> const& led_observer_registrar); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an ABI break - I still don't think that is needed
void mie::LibInputDevice::associate_to_id(MirInputDeviceId id) | ||
{ | ||
try_stop_observing_leds(); | ||
led_observer = std::make_shared<LibInputDeviceLedObserver>(this); | ||
led_observer_registrar->register_interest(led_observer, id); | ||
device_id = id; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks like initialization, but is not in a constructor. Is there a good reason it is here? (And not, say, in mi::DefaultDevice
?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason it is here is to not break the input ABI, but perhaps I'm not seeing something ;)
src/platforms/evdev/platform.cpp
Outdated
auto weak_device = input_device_registry->add_device(devices.back()); | ||
|
||
if (auto device = weak_device.lock()) | ||
new_device->associate_to_id(device->id()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh!
So we're making mi::Device
visible and passing LedObserverRegistrar
around so that we can do two-phase initialization here?
Can we simplify things by registering the callback from DefaultInputDeviceHub
/DefaultDevice
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would require InputDevice
to have set_leds
defined on it, which would break the input ABI again 😄 That's how I had it before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I guess we broke it anyway my change the create_platform
signature 😂
@AlanGriffiths For your AM tomorrow, here's a summary what I have right now:
In this way, only the evdev platform needs to concern itself with the LEDs, because it is the only one that cares about it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have the hardware to test, but this all looks sensible
Looks like a rebase is in order |
fixes #620
What's new?
XkbMapper
takes a callback for when the leds need to be updated for a deviceXkbMapper
notifies the corresponding device of a possible change to its LEDs usingDevice::set_leds
LibInputDevice::set_leds
callslibinput_device_led_update
to update the LEDs