Commit 7f926755 authored by oshima@chromium.org's avatar oshima@chromium.org

Rewrite release event only if press event was rewritten for a given device.

BUG=330567
TEST=TBD

Review URL: https://codereview.chromium.org/144423006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247912 0039d316-1c4b-4281-b951-d872f2087c98
parent 5ded5277
...@@ -1003,15 +1003,20 @@ void EventRewriter::RewriteLocatedEvent(ui::LocatedEvent* event) { ...@@ -1003,15 +1003,20 @@ void EventRewriter::RewriteLocatedEvent(ui::LocatedEvent* event) {
xievent->mods.effective = remapped_native_modifiers; xievent->mods.effective = remapped_native_modifiers;
// Then, remap Alt+Button1 to Button3. // Then, remap Alt+Button1 to Button3.
if ((xievent->mods.effective & Mod1Mask) && xievent->detail == 1) { if ((xievent->evtype == XI_ButtonPress ||
pressed_device_ids_.count(xievent->sourceid)) &&
(xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) {
xievent->mods.effective &= ~Mod1Mask; xievent->mods.effective &= ~Mod1Mask;
xievent->detail = 3; xievent->detail = Button3;
if (xievent->evtype == XI_ButtonRelease) { if (xievent->evtype == XI_ButtonRelease) {
// On the release clear the left button from the existing state and the // On the release clear the left button from the existing state and the
// mods, and set the right button. // mods, and set the right button.
XISetMask(xievent->buttons.mask, 3); XISetMask(xievent->buttons.mask, Button3);
XIClearMask(xievent->buttons.mask, 1); XIClearMask(xievent->buttons.mask, Button1);
xievent->mods.effective &= ~Button1Mask; xievent->mods.effective &= ~Button1Mask;
pressed_device_ids_.erase(xievent->sourceid);
} else {
pressed_device_ids_.insert(xievent->sourceid);
} }
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_ASH_EVENT_REWRITER_H_ #define CHROME_BROWSER_UI_ASH_EVENT_REWRITER_H_
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include "ash/event_rewriter_delegate.h" #include "ash/event_rewriter_delegate.h"
...@@ -78,6 +79,7 @@ class EventRewriter : public ash::EventRewriterDelegate, ...@@ -78,6 +79,7 @@ class EventRewriter : public ash::EventRewriterDelegate,
private: private:
friend class EventRewriterAshTest; friend class EventRewriterAshTest;
friend class EventRewriterTest;
// ash::EventRewriterDelegate overrides: // ash::EventRewriterDelegate overrides:
virtual ash::EventRewriterDelegate::Action RewriteOrFilterKeyEvent( virtual ash::EventRewriterDelegate::Action RewriteOrFilterKeyEvent(
...@@ -223,6 +225,9 @@ class EventRewriter : public ash::EventRewriterDelegate, ...@@ -223,6 +225,9 @@ class EventRewriter : public ash::EventRewriterDelegate,
// A mapping from X11 KeySym keys to KeyCode values. // A mapping from X11 KeySym keys to KeyCode values.
base::hash_map<unsigned long, unsigned long> keysym_to_keycode_map_; base::hash_map<unsigned long, unsigned long> keysym_to_keycode_map_;
// A set of device IDs whose press event has been rewritten.
std::set<int> pressed_device_ids_;
chromeos::input_method::XKeyboard* xkeyboard_for_testing_; chromeos::input_method::XKeyboard* xkeyboard_for_testing_;
scoped_ptr<chromeos::KeyboardDrivenEventRewriter> scoped_ptr<chromeos::KeyboardDrivenEventRewriter>
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "chromeos/ime/mock_xkeyboard.h" #include "chromeos/ime/mock_xkeyboard.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/events/test/events_test_utils_x11.h" #include "ui/events/test/events_test_utils_x11.h"
#include "ui/events/x/touch_factory_x11.h"
#include "ui/gfx/x/x11_types.h" #include "ui/gfx/x/x11_types.h"
namespace { namespace {
...@@ -63,6 +64,8 @@ std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode, ...@@ -63,6 +64,8 @@ std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode,
ui_keycode, ui_flags, ui_type, x_keycode, x_state, x_type); ui_keycode, ui_flags, ui_type, x_keycode, x_state, x_type);
} }
} // namespace
class EventRewriterTest : public testing::Test { class EventRewriterTest : public testing::Test {
public: public:
EventRewriterTest() EventRewriterTest()
...@@ -180,6 +183,11 @@ class EventRewriterTest : public testing::Test { ...@@ -180,6 +183,11 @@ class EventRewriterTest : public testing::Test {
void TestRewriteNumPadKeys(); void TestRewriteNumPadKeys();
void TestRewriteNumPadKeysOnAppleKeyboard(); void TestRewriteNumPadKeysOnAppleKeyboard();
void RewriteLocatedEvent(EventRewriter* rewriter,
ui::LocatedEvent* event) {
rewriter->RewriteLocatedEvent(event);
}
Display* display_; Display* display_;
const KeyCode keycode_a_; const KeyCode keycode_a_;
const KeyCode keycode_alt_l_; const KeyCode keycode_alt_l_;
...@@ -270,7 +278,6 @@ class EventRewriterTest : public testing::Test { ...@@ -270,7 +278,6 @@ class EventRewriterTest : public testing::Test {
chromeos::input_method::MockInputMethodManager* input_method_manager_mock_; chromeos::input_method::MockInputMethodManager* input_method_manager_mock_;
}; };
} // namespace
#else #else
class EventRewriterTest : public testing::Test { class EventRewriterTest : public testing::Test {
public: public:
...@@ -2380,4 +2387,76 @@ TEST_F(EventRewriterAshTest, TopRowKeysAreFunctionKeys) { ...@@ -2380,4 +2387,76 @@ TEST_F(EventRewriterAshTest, TopRowKeysAreFunctionKeys) {
ASSERT_EQ(ui::VKEY_BROWSER_BACK, press_f1.key_code()); ASSERT_EQ(ui::VKEY_BROWSER_BACK, press_f1.key_code());
} }
TEST_F(EventRewriterTest, DontRewriteIfNotRewritten) {
std::vector<unsigned int> device_list;
device_list.push_back(10);
device_list.push_back(11);
ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
TestingPrefServiceSyncable prefs;
EventRewriter rewriter;
rewriter.set_pref_service_for_testing(&prefs);
const int kLeftAndAltFlag = ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN;
{
ui::ScopedXI2Event xev;
xev.InitGenericButtonEvent(10, ui::ET_MOUSE_PRESSED, kLeftAndAltFlag);
ui::MouseEvent press(xev);
// Sanity check.
EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
EXPECT_EQ(kLeftAndAltFlag, press.flags());
RewriteLocatedEvent(&rewriter, &press);
EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
}
{
ui::ScopedXI2Event xev;
xev.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED, kLeftAndAltFlag);
ui::MouseEvent release(xev);
RewriteLocatedEvent(&rewriter, &release);
EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
}
// No ALT in frst click.
{
ui::ScopedXI2Event xev;
xev.InitGenericButtonEvent(
10, ui::ET_MOUSE_PRESSED, ui::EF_LEFT_MOUSE_BUTTON);
ui::MouseEvent press(xev);
RewriteLocatedEvent(&rewriter, &press);
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & press.flags());
}
{
ui::ScopedXI2Event xev;
xev.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED, kLeftAndAltFlag);
ui::MouseEvent release(xev);
RewriteLocatedEvent(&rewriter, &release);
EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
release.flags());
}
// ALT on different device.
{
ui::ScopedXI2Event xev;
xev.InitGenericButtonEvent(11, ui::ET_MOUSE_PRESSED, kLeftAndAltFlag);
ui::MouseEvent press(xev);
RewriteLocatedEvent(&rewriter, &press);
EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
}
{
ui::ScopedXI2Event xev;
xev.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED, kLeftAndAltFlag);
ui::MouseEvent release(xev);
RewriteLocatedEvent(&rewriter, &release);
EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
release.flags());
}
{
ui::ScopedXI2Event xev;
xev.InitGenericButtonEvent(11, ui::ET_MOUSE_RELEASED, kLeftAndAltFlag);
ui::MouseEvent release(xev);
RewriteLocatedEvent(&rewriter, &release);
EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
}
}
#endif // OS_CHROMEOS #endif // OS_CHROMEOS
...@@ -40,6 +40,20 @@ int XKeyEventType(ui::EventType type) { ...@@ -40,6 +40,20 @@ int XKeyEventType(ui::EventType type) {
} }
} }
int XIButtonEventType(ui::EventType type) {
switch (type) {
case ui::ET_MOUSEWHEEL:
case ui::ET_MOUSE_PRESSED:
// The button release X events for mouse wheels are dropped by Aura.
return XI_ButtonPress;
case ui::ET_MOUSE_RELEASED:
return XI_ButtonRelease;
default:
NOTREACHED();
return 0;
}
}
// Converts EventType to XButtonEvent type. // Converts EventType to XButtonEvent type.
int XButtonEventType(ui::EventType type) { int XButtonEventType(ui::EventType type) {
switch (type) { switch (type) {
...@@ -74,14 +88,12 @@ unsigned int XButtonEventButton(ui::EventType type, ...@@ -74,14 +88,12 @@ unsigned int XButtonEventButton(ui::EventType type,
if (type == ui::ET_MOUSEWHEEL) if (type == ui::ET_MOUSEWHEEL)
return Button4; return Button4;
switch (flags) { if (flags & ui::EF_LEFT_MOUSE_BUTTON)
case ui::EF_LEFT_MOUSE_BUTTON: return Button1;
return Button1; if (flags & ui::EF_MIDDLE_MOUSE_BUTTON)
case ui::EF_MIDDLE_MOUSE_BUTTON: return Button2;
return Button2; if (flags & ui::EF_RIGHT_MOUSE_BUTTON)
case ui::EF_RIGHT_MOUSE_BUTTON: return Button3;
return Button3;
}
return 0; return 0;
} }
...@@ -111,7 +123,11 @@ XEvent* CreateXInput2Event(int deviceid, ...@@ -111,7 +123,11 @@ XEvent* CreateXInput2Event(int deviceid,
xiev->detail = tracking_id; xiev->detail = tracking_id;
xiev->event_x = location.x(); xiev->event_x = location.x();
xiev->event_y = location.y(); xiev->event_y = location.y();
if (evtype == XI_ButtonPress || evtype == XI_ButtonRelease) {
xiev->buttons.mask_len = 8;
xiev->buttons.mask = new unsigned char[xiev->buttons.mask_len];
memset(xiev->buttons.mask, 0, xiev->buttons.mask_len);
}
return event; return event;
} }
...@@ -149,6 +165,18 @@ void ScopedXI2Event::InitKeyEvent(EventType type, ...@@ -149,6 +165,18 @@ void ScopedXI2Event::InitKeyEvent(EventType type,
event_->xkey.same_screen = 1; event_->xkey.same_screen = 1;
} }
void ScopedXI2Event::InitGenericButtonEvent(int deviceid,
EventType type,
int flags) {
Cleanup();
event_.reset(CreateXInput2Event(deviceid,
XIButtonEventType(type), 0, gfx::Point()));
XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event_->xcookie.data);
xievent->mods.effective = XEventState(flags);
xievent->detail = XButtonEventButton(type, flags);
XISetMask(xievent->buttons.mask, xievent->detail);
}
void ScopedXI2Event::InitButtonEvent(EventType type, void ScopedXI2Event::InitButtonEvent(EventType type,
int flags) { int flags) {
Cleanup(); Cleanup();
...@@ -238,6 +266,7 @@ void ScopedXI2Event::Cleanup() { ...@@ -238,6 +266,7 @@ void ScopedXI2Event::Cleanup() {
if (xiev) { if (xiev) {
delete[] xiev->valuators.mask; delete[] xiev->valuators.mask;
delete[] xiev->valuators.values; delete[] xiev->valuators.values;
delete[] xiev->buttons.mask;
delete xiev; delete xiev;
} }
} }
......
...@@ -41,6 +41,10 @@ class ScopedXI2Event { ...@@ -41,6 +41,10 @@ class ScopedXI2Event {
void InitButtonEvent(EventType type, void InitButtonEvent(EventType type,
int flags); int flags);
void InitGenericButtonEvent(int deviceid,
EventType type,
int flags);
void InitMouseWheelEvent(int wheel_delta, void InitMouseWheelEvent(int wheel_delta,
int flags); int flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment