Bug 364508, add api to synthesize events at the widget level, r+sr=roc

This commit is contained in:
enndeakin%sympatico.ca 2007-02-26 21:14:19 +00:00
Родитель 5b5339f499
Коммит 663779ca9c
3 изменённых файлов: 161 добавлений и 1 удалений

Просмотреть файл

@ -45,7 +45,7 @@
* getInterface on a DOMWindow.
*/
[scriptable, uuid(cc7f4216-ad89-4687-a793-980662bd10bd)]
[scriptable, uuid(76cdfff8-6f13-43e8-9ed4-36066cd83742)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -81,4 +81,49 @@ interface nsIDOMWindowUtils : nsISupports {
* Force an immediate redraw of this window.
*/
void redraw();
/** Synthesize a mouse event for a window. The event types supported
* are:
* mousedown, mouseup, mousemove, mouseover, mouseout, contextmenu
*
* Events are sent in coordinates offset by aX and aY from the window.
*
* Note that additional events may be fired as a result of this call. For
* instance, typically a click event will be fired as a result of a
* mousedown and mouseup in sequence.
*
* Normally at this level of events, the mouseover and mouseout events are
* only fired when the window is entered or exited. For inter-element
* mouseover and mouseout events, a movemove event fired on the new element
* should be sufficient to generate the correct over and out events as well.
*
* @param aType event type
* @param aX x offset
* @param aY y offset
* @param aButton button to synthesize
* @param aClickCount number of clicks that have been performed
* @param aModifiers modifiers pressed, using constants defined in nsIDOMNSEvent
*/
void sendMouseEvent(in AString aType,
in long aX,
in long aY,
in long aButton,
in long aClickCount,
in long aModifiers);
/**
* Synthesize a key event to the window. The event types supported are:
* keydown, keyup, keypress
*
* Key events generally end up being sent to the focused node.
*
* @param aType event type
* @param aKeyCode key code
* @param aCharCode character code
* @param aModifiers modifiers pressed, using constants defined in nsIDOMNSEvent
*/
void sendKeyEvent(in AString aType,
in long aKeyCode,
in long aCharCode,
in long aModifiers);
};

Просмотреть файл

@ -39,14 +39,19 @@
#include "nsPresContext.h"
#include "nsDOMClassInfo.h"
#include "nsDOMError.h"
#include "nsIDOMNSEvent.h"
#include "nsDOMWindowUtils.h"
#include "nsGlobalWindow.h"
#include "nsIDocument.h"
#include "nsIFocusController.h"
#include "nsContentUtils.h"
#include "nsIFrame.h"
#include "nsIWidget.h"
#include "nsIView.h"
#include "nsGUIEvent.h"
#ifdef MOZ_ENABLE_GTK2
#include <gdk/gdkx.h>
@ -155,3 +160,111 @@ nsDOMWindowUtils::Redraw()
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
PRInt32 aX,
PRInt32 aY,
PRInt32 aButton,
PRInt32 aClickCount,
PRInt32 aModifiers)
{
PRBool hasCap = PR_FALSE;
if (NS_FAILED(nsContentUtils::GetSecurityManager()->IsCapabilityEnabled("UniversalXPConnect", &hasCap))
|| !hasCap)
return NS_ERROR_DOM_SECURITY_ERR;
// get the widget to send the event to
nsIWidget* widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
PRInt32 msg;
if (aType.EqualsLiteral("mousedown"))
msg = NS_MOUSE_BUTTON_DOWN;
else if (aType.EqualsLiteral("mouseup"))
msg = NS_MOUSE_BUTTON_UP;
else if (aType.EqualsLiteral("mousemove"))
msg = NS_MOUSE_MOVE;
else if (aType.EqualsLiteral("mouseover"))
msg = NS_MOUSE_ENTER;
else if (aType.EqualsLiteral("mouseout"))
msg = NS_MOUSE_EXIT;
else if (aType.EqualsLiteral("contextmenu"))
msg = NS_CONTEXTMENU;
else
return NS_ERROR_FAILURE;
nsMouseEvent event(PR_TRUE, msg, widget, nsMouseEvent::eReal);
event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
event.button = aButton;
event.widget = widget;
event.clickCount = aClickCount;
event.time = PR_IntervalNow();
event.refPoint.x = aX;
event.refPoint.y = aY;
nsEventStatus status;
return widget->DispatchEvent(&event, status);
}
NS_IMETHODIMP
nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
PRInt32 aKeyCode,
PRInt32 aCharCode,
PRInt32 aModifiers)
{
PRBool hasCap = PR_FALSE;
if (NS_FAILED(nsContentUtils::GetSecurityManager()->IsCapabilityEnabled("UniversalXPConnect", &hasCap))
|| !hasCap)
return NS_ERROR_DOM_SECURITY_ERR;
// get the widget to send the event to
nsIWidget* widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
PRInt32 msg;
if (aType.EqualsLiteral("keydown"))
msg = NS_KEY_DOWN;
else if (aType.EqualsLiteral("keyup"))
msg = NS_KEY_UP;
else if (aType.EqualsLiteral("keypress"))
msg = NS_KEY_PRESS;
else
return NS_ERROR_FAILURE;
nsKeyEvent event(PR_TRUE, msg, widget);
event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
event.keyCode = aKeyCode;
event.charCode = aCharCode;
event.refPoint.x = event.refPoint.y = 0;
event.time = PR_IntervalNow();
nsEventStatus status;
return widget->DispatchEvent(&event, status);
}
nsIWidget*
nsDOMWindowUtils::GetWidget()
{
if (mWindow) {
nsIDocShell *docShell = mWindow->GetDocShell();
if (docShell) {
nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell));
if (presShell)
return presShell->GetRootFrame()->GetWindow();
}
}
return nsnull;
}

Просмотреть файл

@ -53,4 +53,6 @@ public:
protected:
nsRefPtr<nsGlobalWindow> mWindow;
nsIWidget* GetWidget();
};