зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1137565 part.3 nsWindow for GTK should use TextEventDispatcher for dispatching keyboard events r=m_kato
This commit is contained in:
Родитель
ad8535477c
Коммит
7b8ce29651
|
@ -1456,24 +1456,5 @@ KeymapWrapper::InitKeypressEvent(WidgetKeyboardEvent& aKeyEvent,
|
|||
altLatinCharCodes.mShiftedCharCode));
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
KeymapWrapper::IsKeyPressEventNecessary(GdkEventKey* aGdkKeyEvent)
|
||||
{
|
||||
// If this is a modifier key event, we shouldn't send keypress event.
|
||||
switch (ComputeDOMKeyCode(aGdkKeyEvent)) {
|
||||
case NS_VK_SHIFT:
|
||||
case NS_VK_CONTROL:
|
||||
case NS_VK_ALT:
|
||||
case NS_VK_ALTGR:
|
||||
case NS_VK_WIN:
|
||||
case NS_VK_CAPS_LOCK:
|
||||
case NS_VK_NUM_LOCK:
|
||||
case NS_VK_SCROLL_LOCK:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -123,12 +123,6 @@ public:
|
|||
static void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
|
||||
GdkEventKey* aGdkKeyEvent);
|
||||
|
||||
/**
|
||||
* IsKeyPressEventNecessary() returns TRUE when aGdkKeyEvent should cause
|
||||
* a DOM keypress event. Otherwise, FALSE.
|
||||
*/
|
||||
static bool IsKeyPressEventNecessary(GdkEventKey* aGdkKeyEvent);
|
||||
|
||||
/**
|
||||
* Destroys the singleton KeymapWrapper instance, if it exists.
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/MiscEvents.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/TextEventDispatcher.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
|
@ -2507,8 +2508,7 @@ nsWindow::OnEnterNotifyEvent(GdkEventCrossing *aEvent)
|
|||
WidgetMouseEvent::eReal);
|
||||
|
||||
event.refPoint = GdkEventCoordsToDevicePixels(aEvent->x, aEvent->y);
|
||||
event.time = aEvent->time;
|
||||
event.timeStamp = GetEventTimeStamp(aEvent->time);
|
||||
event.AssignEventTime(GetWidgetEventTime(aEvent->time));
|
||||
|
||||
LOG(("OnEnterNotify: %p\n", (void *)this));
|
||||
|
||||
|
@ -2548,8 +2548,7 @@ nsWindow::OnLeaveNotifyEvent(GdkEventCrossing *aEvent)
|
|||
WidgetMouseEvent::eReal);
|
||||
|
||||
event.refPoint = GdkEventCoordsToDevicePixels(aEvent->x, aEvent->y);
|
||||
event.time = aEvent->time;
|
||||
event.timeStamp = GetEventTimeStamp(aEvent->time);
|
||||
event.AssignEventTime(GetWidgetEventTime(aEvent->time));
|
||||
|
||||
event.exit = is_top_level_mouse_exit(mGdkWindow, aEvent)
|
||||
? WidgetMouseEvent::eTopLevel : WidgetMouseEvent::eChild;
|
||||
|
@ -2623,23 +2622,20 @@ nsWindow::OnMotionNotifyEvent(GdkEventMotion *aEvent)
|
|||
|
||||
modifierState = xevent.xmotion.state;
|
||||
|
||||
event.time = xevent.xmotion.time;
|
||||
event.timeStamp = GetEventTimeStamp(xevent.xmotion.time);
|
||||
event.AssignEventTime(GetWidgetEventTime(xevent.xmotion.time));
|
||||
#else
|
||||
event.refPoint = GdkEventCoordsToDevicePixels(aEvent->x, aEvent->y);
|
||||
|
||||
modifierState = aEvent->state;
|
||||
|
||||
event.time = aEvent->time;
|
||||
event.timeStamp = GetEventTimeStamp(aEvent->time);
|
||||
event.AssignEventTime(GetWidgetEventTime(aEvent->time));
|
||||
#endif /* MOZ_X11 */
|
||||
} else {
|
||||
event.refPoint = GetRefPoint(this, aEvent);
|
||||
|
||||
modifierState = aEvent->state;
|
||||
|
||||
event.time = aEvent->time;
|
||||
event.timeStamp = GetEventTimeStamp(aEvent->time);
|
||||
event.AssignEventTime(GetWidgetEventTime(aEvent->time));
|
||||
}
|
||||
|
||||
KeymapWrapper::InitInputEvent(event, modifierState);
|
||||
|
@ -2729,8 +2725,7 @@ nsWindow::InitButtonEvent(WidgetMouseEvent& aEvent,
|
|||
|
||||
KeymapWrapper::InitInputEvent(aEvent, modifierState);
|
||||
|
||||
aEvent.time = aGdkEvent->time;
|
||||
aEvent.timeStamp = GetEventTimeStamp(aGdkEvent->time);
|
||||
aEvent.AssignEventTime(GetWidgetEventTime(aGdkEvent->time));
|
||||
|
||||
switch (aGdkEvent->type) {
|
||||
case GDK_2BUTTON_PRESS:
|
||||
|
@ -2981,12 +2976,26 @@ nsWindow::DispatchKeyDownEvent(GdkEventKey *aEvent, bool *aCancelled)
|
|||
return false;
|
||||
}
|
||||
|
||||
// send the key down event
|
||||
WidgetKeyboardEvent downEvent(true, eKeyDown, this);
|
||||
KeymapWrapper::InitKeyEvent(downEvent, aEvent);
|
||||
nsEventStatus status = DispatchInputEvent(&downEvent);
|
||||
RefPtr<TextEventDispatcher> dispatcher = GetTextEventDispatcher();
|
||||
nsresult rv = dispatcher->BeginNativeInputTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WidgetKeyboardEvent keydownEvent(true, eKeyDown, this);
|
||||
KeymapWrapper::InitKeyEvent(keydownEvent, aEvent);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
bool dispatched =
|
||||
dispatcher->DispatchKeyboardEvent(eKeyDown, keydownEvent,
|
||||
status, aEvent);
|
||||
*aCancelled = (status == nsEventStatus_eConsumeNoDefault);
|
||||
return true;
|
||||
return dispatched ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
WidgetEventTime
|
||||
nsWindow::GetWidgetEventTime(guint32 aEventTime)
|
||||
{
|
||||
return WidgetEventTime(aEventTime, GetEventTimeStamp(aEventTime));
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
|
@ -3025,6 +3034,9 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent)
|
|||
|
||||
// if we are in the middle of composing text, XIM gets to see it
|
||||
// before mozilla does.
|
||||
// FYI: Don't dispatch keydown event before notifying IME of the event
|
||||
// because IME may send a key event synchronously and consume the
|
||||
// original event.
|
||||
bool IMEWasEnabled = false;
|
||||
if (mIMContext) {
|
||||
IMEWasEnabled = mIMContext->IsEnabled();
|
||||
|
@ -3033,8 +3045,6 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent)
|
|||
}
|
||||
}
|
||||
|
||||
nsEventStatus status;
|
||||
|
||||
// work around for annoying things.
|
||||
if (IsCtrlAltTab(aEvent)) {
|
||||
return TRUE;
|
||||
|
@ -3065,14 +3075,6 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent)
|
|||
}
|
||||
}
|
||||
|
||||
// Don't pass modifiers as eKeyPress events.
|
||||
// TODO: Instead of selectively excluding some keys from eKeyPress events,
|
||||
// we should instead selectively include (as per MSDN spec; no official
|
||||
// spec covers KeyPress events).
|
||||
if (!KeymapWrapper::IsKeyPressEventNecessary(aEvent)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef MOZ_X11
|
||||
#if ! defined AIX // no XFree86 on AIX 5L
|
||||
// Look for specialized app-command keys
|
||||
|
@ -3109,41 +3111,43 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent)
|
|||
#endif /* ! AIX */
|
||||
#endif /* MOZ_X11 */
|
||||
|
||||
WidgetKeyboardEvent event(true, eKeyPress, this);
|
||||
KeymapWrapper::InitKeyEvent(event, aEvent);
|
||||
WidgetKeyboardEvent keypressEvent(true, eKeyPress, this);
|
||||
KeymapWrapper::InitKeyEvent(keypressEvent, aEvent);
|
||||
|
||||
// before we dispatch a key, check if it's the context menu key.
|
||||
// If so, send a context menu key event instead.
|
||||
if (is_context_menu_key(event)) {
|
||||
if (is_context_menu_key(keypressEvent)) {
|
||||
WidgetMouseEvent contextMenuEvent(true, eContextMenu, this,
|
||||
WidgetMouseEvent::eReal,
|
||||
WidgetMouseEvent::eContextMenuKey);
|
||||
|
||||
contextMenuEvent.refPoint = LayoutDeviceIntPoint(0, 0);
|
||||
contextMenuEvent.time = aEvent->time;
|
||||
contextMenuEvent.timeStamp = GetEventTimeStamp(aEvent->time);
|
||||
contextMenuEvent.AssignEventTime(GetWidgetEventTime(aEvent->time));
|
||||
contextMenuEvent.clickCount = 1;
|
||||
KeymapWrapper::InitInputEvent(contextMenuEvent, aEvent->state);
|
||||
status = DispatchInputEvent(&contextMenuEvent);
|
||||
}
|
||||
else {
|
||||
DispatchInputEvent(&contextMenuEvent);
|
||||
} else {
|
||||
RefPtr<TextEventDispatcher> dispatcher = GetTextEventDispatcher();
|
||||
nsresult rv = dispatcher->BeginNativeInputTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// If the character code is in the BMP, send the key press event.
|
||||
// Otherwise, send a compositionchange event with the equivalent UTF-16
|
||||
// string.
|
||||
if (IS_IN_BMP(event.charCode)) {
|
||||
status = DispatchInputEvent(&event);
|
||||
}
|
||||
else {
|
||||
WidgetCompositionEvent compositionChangeEvent(
|
||||
true, eCompositionChange, this);
|
||||
char16_t textString[3];
|
||||
textString[0] = H_SURROGATE(event.charCode);
|
||||
textString[1] = L_SURROGATE(event.charCode);
|
||||
textString[2] = 0;
|
||||
compositionChangeEvent.mData = textString;
|
||||
compositionChangeEvent.time = event.time;
|
||||
compositionChangeEvent.timeStamp = GetEventTimeStamp(aEvent->time);
|
||||
DispatchEvent(&compositionChangeEvent, status);
|
||||
// TODO: Investigate other browser's behavior in this case because
|
||||
// this hack is odd for UI Events.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
if (IS_IN_BMP(keypressEvent.charCode)) {
|
||||
dispatcher->MaybeDispatchKeypressEvents(keypressEvent,
|
||||
status, aEvent);
|
||||
} else {
|
||||
nsAutoString str;
|
||||
str.Append(H_SURROGATE(keypressEvent.charCode));
|
||||
str.Append(L_SURROGATE(keypressEvent.charCode));
|
||||
WidgetEventTime eventTime = GetWidgetEventTime(aEvent->time);
|
||||
dispatcher->CommitComposition(status, &str, &eventTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3159,11 +3163,16 @@ nsWindow::OnKeyReleaseEvent(GdkEventKey *aEvent)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// send the key event as a key up event
|
||||
WidgetKeyboardEvent event(true, eKeyUp, this);
|
||||
KeymapWrapper::InitKeyEvent(event, aEvent);
|
||||
RefPtr<TextEventDispatcher> dispatcher = GetTextEventDispatcher();
|
||||
nsresult rv = dispatcher->BeginNativeInputTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(void)DispatchInputEvent(&event);
|
||||
WidgetKeyboardEvent keyupEvent(true, eKeyUp, this);
|
||||
KeymapWrapper::InitKeyEvent(keyupEvent, aEvent);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
dispatcher->DispatchKeyboardEvent(eKeyUp, keyupEvent, status, aEvent);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -3224,8 +3233,7 @@ nsWindow::OnScrollEvent(GdkEventScroll *aEvent)
|
|||
|
||||
KeymapWrapper::InitInputEvent(wheelEvent, aEvent->state);
|
||||
|
||||
wheelEvent.time = aEvent->time;
|
||||
wheelEvent.timeStamp = GetEventTimeStamp(aEvent->time);
|
||||
wheelEvent.AssignEventTime(GetWidgetEventTime(aEvent->time));
|
||||
|
||||
DispatchInputEvent(&wheelEvent);
|
||||
}
|
||||
|
@ -3380,8 +3388,7 @@ nsWindow::DispatchDragEvent(EventMessage aMsg, const LayoutDeviceIntPoint& aRefP
|
|||
}
|
||||
|
||||
event.refPoint = aRefPoint;
|
||||
event.time = aTime;
|
||||
event.timeStamp = GetEventTimeStamp(aTime);
|
||||
event.AssignEventTime(GetWidgetEventTime(aTime));
|
||||
|
||||
DispatchInputEvent(&event);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ class CurrentX11TimeGetter;
|
|||
class nsWindow : public nsBaseWidget
|
||||
{
|
||||
public:
|
||||
typedef mozilla::WidgetEventTime WidgetEventTime;
|
||||
|
||||
nsWindow();
|
||||
|
||||
static void ReleaseGlobals();
|
||||
|
@ -281,6 +283,7 @@ public:
|
|||
// otherwise, FALSE.
|
||||
bool DispatchKeyDownEvent(GdkEventKey *aEvent,
|
||||
bool *aIsCancelled);
|
||||
WidgetEventTime GetWidgetEventTime(guint32 aEventTime);
|
||||
mozilla::TimeStamp GetEventTimeStamp(guint32 aEventTime);
|
||||
mozilla::CurrentX11TimeGetter* GetCurrentTimeGetter();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче