Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Unified Diff: chrome/browser/chromeos/events/event_rewriter.cc

Issue 653423004: Suppress Xorg generated key repeat events for Hotrod remote (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/events/event_rewriter.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/events/event_rewriter.cc
diff --git a/chrome/browser/chromeos/events/event_rewriter.cc b/chrome/browser/chromeos/events/event_rewriter.cc
index 2316a4a0228adb4961b84057dc0e22efbf3664ad..82111e2412ffc89eaa810f30caa1a6f1908980a6 100644
--- a/chrome/browser/chromeos/events/event_rewriter.cc
+++ b/chrome/browser/chromeos/events/event_rewriter.cc
@@ -30,7 +30,13 @@
#if defined(USE_X11)
#include <X11/extensions/XInput2.h>
+#include <X11/Xatom.h>
#include <X11/Xlib.h>
+
+#ifndef XI_PROP_PRODUCT_ID
+#define XI_PROP_PRODUCT_ID "Device Product ID"
+#endif
+
// Get rid of macros from Xlib.h that conflicts with other parts of the code.
#undef RootWindow
#undef Status
@@ -43,6 +49,12 @@ namespace chromeos {
namespace {
+// Hotrod controller vendor/product ids.
+const int kHotrodRemoteVendorId = 0x0471;
+const int kHotrodRemoteProductId = 0x21cc;
+const int kUnknownVendorId = -1;
+const int kUnknownProductId = -1;
+
// Table of key properties of remappable keys and/or remapping targets.
// This is searched in two distinct ways:
// - |remap_to| is an |input_method::ModifierKey|, which is the form
@@ -127,10 +139,21 @@ bool IsExtensionCommandRegistered(ui::KeyboardCode key_code, int flags) {
->IsRegistered(accelerator);
}
-EventRewriter::DeviceType GetDeviceType(const std::string& device_name) {
+EventRewriter::DeviceType GetDeviceType(const std::string& device_name,
kpschoedel 2014/10/20 16:24:37 I've been hoping to move these keyboard-type prope
+ int vendor_id,
+ int product_id) {
+ if (vendor_id == kHotrodRemoteVendorId &&
+ product_id == kHotrodRemoteProductId) {
+ return EventRewriter::kDeviceHotrodRemote;
+ }
+
+ if (LowerCaseEqualsASCII(device_name, "virtual core keyboard"))
+ return EventRewriter::kDeviceVirtualCoreKeyboard;
+
std::vector<std::string> tokens;
Tokenize(device_name, " .", &tokens);
+
// If the |device_name| contains the two words, "apple" and "keyboard", treat
// it as an Apple keyboard.
bool found_apple = false;
@@ -165,7 +188,10 @@ EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedForTesting(
const std::string& device_name) {
// Tests must avoid XI2 reserved device IDs.
DCHECK((device_id < 0) || (device_id > 1));
- return KeyboardDeviceAddedInternal(device_id, device_name);
+ return KeyboardDeviceAddedInternal(device_id,
+ device_name,
+ kUnknownVendorId,
+ kUnknownProductId);
}
void EventRewriter::RewriteMouseButtonEventForTesting(
@@ -280,8 +306,20 @@ void EventRewriter::BuildRewrittenKeyEvent(
}
void EventRewriter::DeviceKeyPressedOrReleased(int device_id) {
- if (!device_id_to_type_.count(device_id))
- KeyboardDeviceAdded(device_id);
+ std::map<int, DeviceType>::const_iterator iter =
+ device_id_to_type_.find(device_id);
+ DeviceType type;
+ if (iter != device_id_to_type_.end())
+ type = iter->second;
+ else
+ type = KeyboardDeviceAdded(device_id);
+
+ // Ignore virtual Xorg keyboard (magic that generates key repeat
+ // events). Pretend that the previous real keyboard is the one that is still
+ // in use.
+ if (type == kDeviceVirtualCoreKeyboard)
+ return;
+
last_keyboard_device_id_ = device_id;
}
@@ -293,6 +331,14 @@ const PrefService* EventRewriter::GetPrefService() const {
}
bool EventRewriter::IsAppleKeyboard() const {
+ return IsLastKeyboardOfType(kDeviceAppleKeyboard);
+}
+
+bool EventRewriter::IsHotrodRemote() const {
+ return IsLastKeyboardOfType(kDeviceHotrodRemote);
+}
+
+bool EventRewriter::IsLastKeyboardOfType(DeviceType device_type) const {
if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE)
return false;
@@ -305,7 +351,7 @@ bool EventRewriter::IsAppleKeyboard() const {
}
const DeviceType type = iter->second;
- return type == kDeviceAppleKeyboard;
+ return type == device_type;
}
bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const {
@@ -387,6 +433,14 @@ ui::EventRewriteStatus EventRewriter::RewriteKeyEvent(
return ui::EVENT_REWRITE_CONTINUE;
if (key_event.source_device_id() != ui::ED_UNKNOWN_DEVICE)
DeviceKeyPressedOrReleased(key_event.source_device_id());
+
+ // Drop repeated keys from Hotrod remote.
+ if ((key_event.flags() & ui::EF_IS_REPEAT) &&
+ (key_event.type() == ui::ET_KEY_PRESSED) &&
+ IsHotrodRemote() && key_event.key_code() != ui::VKEY_BACK) {
+ return ui::EVENT_REWRITE_DISCARD;
+ }
+
MutableKeyState state = {key_event.flags(), key_event.key_code()};
// Do not rewrite an event sent by ui_controls::SendKeyPress(). See
// crbug.com/136465.
@@ -394,6 +448,7 @@ ui::EventRewriteStatus EventRewriter::RewriteKeyEvent(
RewriteModifierKeys(key_event, &state);
RewriteNumPadKeys(key_event, &state);
}
+
ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
bool is_sticky_key_extension_command = false;
if (sticky_keys_controller_) {
@@ -854,11 +909,22 @@ int EventRewriter::RewriteModifierClick(const ui::MouseEvent& mouse_event,
EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal(
int device_id,
- const std::string& device_name) {
- const DeviceType type = GetDeviceType(device_name);
+ const std::string& device_name,
+ int vendor_id,
+ int product_id) {
+ const DeviceType type = GetDeviceType(device_name, vendor_id, product_id);
if (type == kDeviceAppleKeyboard) {
VLOG(1) << "Apple keyboard '" << device_name << "' connected: "
<< "id=" << device_id;
+ } else if (type == kDeviceHotrodRemote) {
+ VLOG(1) << "Hotrod remote '" << device_name << "' connected: "
+ << "id=" << device_id;
+ } else if (type == kDeviceVirtualCoreKeyboard) {
+ VLOG(1) << "Xorg virtual '" << device_name << "' connected: "
+ << "id=" << device_id;
+ } else {
+ VLOG(1) << "Unknown keyboard '" << device_name << "' connected: "
+ << "id=" << device_id;
}
// Always overwrite the existing device_id since the X server may reuse a
// device id for an unattached device.
@@ -866,15 +932,18 @@ EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal(
return type;
}
-void EventRewriter::KeyboardDeviceAdded(int device_id) {
+EventRewriter::DeviceType EventRewriter::KeyboardDeviceAdded(int device_id) {
#if defined(USE_X11)
DCHECK_NE(XIAllDevices, device_id);
DCHECK_NE(XIAllMasterDevices, device_id);
if (device_id == XIAllDevices || device_id == XIAllMasterDevices) {
LOG(ERROR) << "Unexpected device_id passed: " << device_id;
- return;
+ return kDeviceUnknown;
}
+ Atom product_id_atom =
+ XInternAtom(gfx::GetXDisplay(), XI_PROP_PRODUCT_ID, 1);
+
int ndevices_return = 0;
XIDeviceInfo* device_info =
XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return);
@@ -883,19 +952,53 @@ void EventRewriter::KeyboardDeviceAdded(int device_id) {
// the number of devices found should be either 0 (not found) or 1.
if (!device_info) {
LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown.";
- return;
+ return kDeviceUnknown;
}
+ DeviceType dev_type;
DCHECK_EQ(1, ndevices_return);
for (int i = 0; i < ndevices_return; ++i) {
+ // Get keyboard product and vendor id.
+ int vendor_id = kUnknownVendorId;
+ int product_id = kUnknownProductId;
+ uint32* product_info = NULL;
+ Atom type;
+ int format_return;
+ unsigned long num_items_return;
+ unsigned long bytes_after_return;
+ if (XIGetProperty(gfx::GetXDisplay(),
+ device_info[i].deviceid,
+ product_id_atom,
+ 0,
+ 2,
+ 0,
+ XA_INTEGER,
+ &type,
+ &format_return,
+ &num_items_return,
+ &bytes_after_return,
+ reinterpret_cast<unsigned char **>(&product_info)) == 0 &&
+ product_info) {
+ vendor_id = product_info[0];
+ product_id = product_info[1];
+ }
kpschoedel 2014/10/20 16:24:37 Thanks; this will help for crbug.com/175224. (Now
+
DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above.
DCHECK(device_info[i].name);
- KeyboardDeviceAddedInternal(device_info[i].deviceid, device_info[i].name);
+ dev_type = KeyboardDeviceAddedInternal(device_info[i].deviceid,
+ device_info[i].name,
+ vendor_id,
+ product_id);
}
-
XIFreeDeviceInfo(device_info);
+ return dev_type;
#else
- KeyboardDeviceAddedInternal(device_id, "keyboard");
+ // TODO(spang): Figure out where we can get keyboard vendor/product id from in
+ // Ozone/Freon version.
kpschoedel 2014/10/20 16:24:37 ioctl EVIOCGID, I think.
+ return KeyboardDeviceAddedInternal(device_id,
+ "keyboard",
+ kUnknownVendorId,
+ kUnknownProductId);
#endif
}
« no previous file with comments | « chrome/browser/chromeos/events/event_rewriter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698