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

Unified Diff: ash/wm/tablet_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc

Issue 2905383003: (fix landed) Reland of name MaximizeMode to TabletMode (Closed)
Patch Set: Created 3 years, 7 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
Index: ash/wm/tablet_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc
diff --git a/ash/wm/tablet_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc b/ash/wm/tablet_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e9de2bd0432f1e1addfe017e5861ce73956cf1de
--- /dev/null
+++ b/ash/wm/tablet_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc
@@ -0,0 +1,165 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/tablet_mode/scoped_disable_internal_mouse_and_keyboard_x11.h"
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XInput2.h>
+
+#include <memory>
+#include <set>
+#include <utility>
+
+#include "ash/display/window_tree_host_manager.h"
+#include "ash/shell.h"
+#include "base/strings/string_util.h"
+#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/aura/env.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/events/devices/input_device.h"
+#include "ui/events/devices/x11/device_data_manager_x11.h"
+#include "ui/events/devices/x11/device_list_cache_x11.h"
+#include "ui/events/event.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/keycodes/keyboard_codes_posix.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/x/x11_types.h"
+
+namespace ash {
+
+namespace {
+
+// The name of the xinput device corresponding to the internal touchpad.
+const char kInternalTouchpadName[] = "Elan Touchpad";
+
+// Repeated key events have their source set to the core keyboard device.
+// These must be disabled also until http://crbug.com/402898 is resolved.
+const char kCoreKeyboardName[] = "Virtual core keyboard";
+
+// Device id used to indicate that a device has not been detected.
+const int kDeviceIdNone = -1;
+
+gfx::Point GetMouseLocationInScreen() {
+ return aura::Env::GetInstance()->last_mouse_location();
+}
+
+void SetMouseLocationInScreen(const gfx::Point& screen_location) {
+ const display::Display& display =
+ Shell::Get()->display_manager()->FindDisplayContainingPoint(
+ screen_location);
+ if (!display.is_valid())
+ return;
+ aura::Window* root_window =
+ Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId(
+ display.id());
+ gfx::Point host_location(screen_location);
+ aura::client::ScreenPositionClient* client =
+ aura::client::GetScreenPositionClient(root_window);
+ if (client)
+ client->ConvertPointFromScreen(root_window, &host_location);
+ root_window->GetHost()->MoveCursorToLocationInDIP(host_location);
+}
+
+} // namespace
+
+ScopedDisableInternalMouseAndKeyboardX11::
+ ScopedDisableInternalMouseAndKeyboardX11()
+ : touchpad_device_id_(kDeviceIdNone),
+ keyboard_device_id_(kDeviceIdNone),
+ core_keyboard_device_id_(kDeviceIdNone),
+ last_mouse_location_(GetMouseLocationInScreen()) {
+ ui::DeviceDataManagerX11* device_data_manager =
+ ui::DeviceDataManagerX11::GetInstance();
+ if (device_data_manager->IsXInput2Available()) {
+ const XIDeviceList& xi_dev_list =
+ ui::DeviceListCacheX11::GetInstance()->GetXI2DeviceList(
+ gfx::GetXDisplay());
+ for (int i = 0; i < xi_dev_list.count; ++i) {
+ std::string device_name(xi_dev_list[i].name);
+ base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name);
+ if (device_name == kInternalTouchpadName) {
+ if (device_data_manager->IsDeviceEnabled(xi_dev_list[i].deviceid)) {
+ // If the touchpad is already disabled we will do nothing about it.
+ // This will result in doing nothing in the destructor as well since
+ // |touchpad_device_id_| will remain |kDeviceIdNone|.
+ touchpad_device_id_ = xi_dev_list[i].deviceid;
+ device_data_manager->DisableDevice(touchpad_device_id_);
+ Shell::Get()->cursor_manager()->HideCursor();
+ }
+ } else if (device_name == kCoreKeyboardName) {
+ core_keyboard_device_id_ = xi_dev_list[i].deviceid;
+ device_data_manager->DisableDevice(core_keyboard_device_id_);
+ }
+ }
+
+ for (const ui::InputDevice& device :
+ device_data_manager->GetKeyboardDevices()) {
+ if (device.type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL) {
+ keyboard_device_id_ = device.id;
+ device_data_manager->DisableDevice(keyboard_device_id_);
+ break;
+ }
+ }
+ }
+ // Allow the accessible keys present on the side of some devices to continue
+ // working.
+ std::unique_ptr<std::set<ui::KeyboardCode>> excepted_keys(
+ new std::set<ui::KeyboardCode>);
+ excepted_keys->insert(ui::VKEY_VOLUME_DOWN);
+ excepted_keys->insert(ui::VKEY_VOLUME_UP);
+ excepted_keys->insert(ui::VKEY_POWER);
+ device_data_manager->SetDisabledKeyboardAllowedKeys(std::move(excepted_keys));
+ ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
+}
+
+ScopedDisableInternalMouseAndKeyboardX11::
+ ~ScopedDisableInternalMouseAndKeyboardX11() {
+ ui::DeviceDataManagerX11* device_data_manager =
+ static_cast<ui::DeviceDataManagerX11*>(
+ ui::DeviceDataManager::GetInstance());
+ if (touchpad_device_id_ != kDeviceIdNone) {
+ device_data_manager->EnableDevice(touchpad_device_id_);
+ Shell::Get()->cursor_manager()->ShowCursor();
+ }
+ if (keyboard_device_id_ != kDeviceIdNone)
+ device_data_manager->EnableDevice(keyboard_device_id_);
+ if (core_keyboard_device_id_ != kDeviceIdNone)
+ device_data_manager->EnableDevice(core_keyboard_device_id_);
+ device_data_manager->SetDisabledKeyboardAllowedKeys(
+ std::unique_ptr<std::set<ui::KeyboardCode>>());
+ ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
+}
+
+void ScopedDisableInternalMouseAndKeyboardX11::WillProcessEvent(
+ const ui::PlatformEvent& event) {}
+
+void ScopedDisableInternalMouseAndKeyboardX11::DidProcessEvent(
+ const ui::PlatformEvent& event) {
+ if (event->type != GenericEvent)
+ return;
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
+ ui::DeviceDataManagerX11* device_data_manager =
+ static_cast<ui::DeviceDataManagerX11*>(
+ ui::DeviceDataManager::GetInstance());
+ if (xievent->evtype != XI_Motion ||
+ device_data_manager->IsFlingEvent(*event) ||
+ device_data_manager->IsScrollEvent(*event) ||
+ device_data_manager->IsCMTMetricsEvent(*event)) {
+ return;
+ }
+ if (xievent->sourceid == touchpad_device_id_) {
+ // The cursor will have already moved even though the move event will be
+ // blocked. Move the mouse cursor back to its last known location resulting
+ // from an external mouse to prevent the internal touchpad from moving it.
+ SetMouseLocationInScreen(last_mouse_location_);
+ } else {
+ // Track the last location seen from an external mouse event.
+ last_mouse_location_ = GetMouseLocationInScreen();
+ }
+}
+
+} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698