зеркало из https://github.com/mozilla/gecko-dev.git
Checkpointing changes. Mouse events being hooked up, invalidation implemented.
This commit is contained in:
Родитель
d89032c7bf
Коммит
a278eab591
|
@ -114,7 +114,7 @@ moz_drawingarea_create_windows (MozDrawingarea *drawingarea, GdkWindow *parent,
|
|||
gint attributes_mask = 0;
|
||||
|
||||
/* create the clipping window */
|
||||
attributes.event_mask = (GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK);
|
||||
attributes.event_mask = 0;
|
||||
attributes.x = 0;
|
||||
attributes.y = 0;
|
||||
attributes.width = 1;
|
||||
|
@ -135,6 +135,10 @@ moz_drawingarea_create_windows (MozDrawingarea *drawingarea, GdkWindow *parent,
|
|||
gtk default which is BlackPixel. */
|
||||
gdk_window_set_back_pixmap(drawingarea->clip_window, NULL, FALSE);
|
||||
|
||||
attributes.event_mask = (GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK);
|
||||
/* create the inner window */
|
||||
drawingarea->inner_window = gdk_window_new (drawingarea->clip_window,
|
||||
&attributes, attributes_mask);
|
||||
|
|
|
@ -68,7 +68,8 @@ nsCommonWidget::InitPaintEvent(nsPaintEvent &aEvent)
|
|||
aEvent.widget = NS_STATIC_CAST(nsIWidget *, this);
|
||||
}
|
||||
|
||||
void nsCommonWidget::InitSizeEvent(nsSizeEvent &aEvent)
|
||||
void
|
||||
nsCommonWidget::InitSizeEvent(nsSizeEvent &aEvent)
|
||||
{
|
||||
memset(&aEvent, 0, sizeof(nsSizeEvent));
|
||||
aEvent.eventStructType = NS_SIZE_EVENT;
|
||||
|
@ -76,7 +77,8 @@ void nsCommonWidget::InitSizeEvent(nsSizeEvent &aEvent)
|
|||
aEvent.widget = NS_STATIC_CAST(nsIWidget *, this);
|
||||
}
|
||||
|
||||
void nsCommonWidget::InitGUIEvent(nsGUIEvent &aEvent, PRUint32 aMsg)
|
||||
void
|
||||
nsCommonWidget::InitGUIEvent(nsGUIEvent &aEvent, PRUint32 aMsg)
|
||||
{
|
||||
memset(&aEvent, 0, sizeof(nsGUIEvent));
|
||||
aEvent.eventStructType = NS_GUI_EVENT;
|
||||
|
@ -84,6 +86,55 @@ void nsCommonWidget::InitGUIEvent(nsGUIEvent &aEvent, PRUint32 aMsg)
|
|||
aEvent.widget = NS_STATIC_CAST(nsIWidget *, this);
|
||||
}
|
||||
|
||||
void
|
||||
nsCommonWidget::InitMouseEvent(nsMouseEvent &aEvent, PRUint32 aMsg)
|
||||
{
|
||||
memset(&aEvent, 0, sizeof(nsMouseEvent));
|
||||
aEvent.eventStructType = NS_MOUSE_EVENT;
|
||||
aEvent.message = aMsg;
|
||||
aEvent.widget = NS_STATIC_CAST(nsIWidget *, this);
|
||||
}
|
||||
|
||||
void
|
||||
nsCommonWidget::InitButtonEvent(nsMouseEvent &aEvent, PRUint32 aMsg,
|
||||
GdkEventButton *aGdkEvent)
|
||||
{
|
||||
memset(&aEvent, 0, sizeof(nsMouseEvent));
|
||||
aEvent.eventStructType = NS_MOUSE_EVENT;
|
||||
aEvent.message = aMsg;
|
||||
aEvent.widget = NS_STATIC_CAST(nsIWidget *, this);
|
||||
|
||||
aEvent.point.x = nscoord(aGdkEvent->x);
|
||||
aEvent.point.y = nscoord(aGdkEvent->y);
|
||||
|
||||
aEvent.isShift = aGdkEvent->state & GDK_SHIFT_MASK;
|
||||
aEvent.isControl = aGdkEvent->state & GDK_CONTROL_MASK;
|
||||
aEvent.isAlt = aGdkEvent->state & GDK_MOD1_MASK;
|
||||
aEvent.isMeta = PR_FALSE; // Gtk+ doesn't have meta
|
||||
|
||||
switch (aGdkEvent->type) {
|
||||
case GDK_2BUTTON_PRESS:
|
||||
aEvent.clickCount = 2;
|
||||
break;
|
||||
case GDK_3BUTTON_PRESS:
|
||||
aEvent.clickCount = 3;
|
||||
break;
|
||||
// default is one click
|
||||
default:
|
||||
aEvent.clickCount = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsCommonWidget::InitMouseScrollEvent(nsMouseScrollEvent &aEvent, PRUint32 aMsg)
|
||||
{
|
||||
memset(&aEvent, 0, sizeof(nsMouseScrollEvent));
|
||||
aEvent.eventStructType = NS_MOUSE_SCROLL_EVENT;
|
||||
aEvent.message = aMsg;
|
||||
aEvent.widget = NS_STATIC_CAST(nsIWidget *, this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommonWidget::DispatchEvent(nsGUIEvent *aEvent,
|
||||
nsEventStatus &aStatus)
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "nsBaseWidget.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include <gdk/gdkevents.h>
|
||||
|
||||
class nsCommonWidget : public nsBaseWidget {
|
||||
public:
|
||||
|
@ -52,6 +53,10 @@ class nsCommonWidget : public nsBaseWidget {
|
|||
void InitPaintEvent(nsPaintEvent &aEvent);
|
||||
void InitSizeEvent(nsSizeEvent &aEvent);
|
||||
void InitGUIEvent(nsGUIEvent &aEvent, PRUint32 aMsg);
|
||||
void InitMouseEvent(nsMouseEvent &aEvent, PRUint32 aMsg);
|
||||
void InitButtonEvent(nsMouseEvent &aEvent, PRUint32 aMsg,
|
||||
GdkEventButton *aEvent);
|
||||
void InitMouseScrollEvent(nsMouseScrollEvent &aEvent, PRUint32 aMsg);
|
||||
NS_IMETHOD DispatchEvent(nsGUIEvent *aEvent,
|
||||
nsEventStatus &aStatus);
|
||||
|
||||
|
|
|
@ -36,16 +36,27 @@
|
|||
#include "nsWindow.h"
|
||||
#include "nsToolkit.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIRegion.h"
|
||||
|
||||
#include <gtk/gtkwindow.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
static gboolean expose_event_cb (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
static gboolean configure_event_cb(GtkWidget *widget,
|
||||
static gboolean configure_event_cb (GtkWidget *widget,
|
||||
GdkEventConfigure *event);
|
||||
static gboolean delete_event_cb (GtkWidget *widget,
|
||||
GdkEventAny *event);
|
||||
static gboolean enter_notify_event_cb (GtkWidget *widget,
|
||||
GdkEventCrossing *event);
|
||||
static gboolean leave_notify_event_cb (GtkWidget *widget,
|
||||
GdkEventCrossing *event);
|
||||
static gboolean motion_notify_event_cb (GtkWidget *widget,
|
||||
GdkEventMotion *event);
|
||||
static gboolean button_press_event_cb (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gboolean button_release_event_cb (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
|
||||
nsWindow::nsWindow()
|
||||
{
|
||||
|
@ -292,21 +303,51 @@ nsWindow::Validate()
|
|||
NS_IMETHODIMP
|
||||
nsWindow::Invalidate(PRBool aIsSynchronous)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
GdkRectangle rect;
|
||||
|
||||
rect.x = mBounds.x;
|
||||
rect.y = mBounds.y;
|
||||
rect.width = mBounds.width;
|
||||
rect.height = mBounds.height;
|
||||
|
||||
gdk_window_invalidate_rect(mDrawingarea->inner_window,
|
||||
&rect, TRUE);
|
||||
if (aIsSynchronous)
|
||||
gdk_window_process_updates(mDrawingarea->inner_window, TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Invalidate(const nsRect &aRect,
|
||||
PRBool aIsSynchronous)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
GdkRectangle rect;
|
||||
|
||||
rect.x = aRect.x;
|
||||
rect.y = aRect.y;
|
||||
rect.width = aRect.width;
|
||||
rect.height = aRect.height;
|
||||
|
||||
gdk_window_invalidate_rect(mDrawingarea->inner_window,
|
||||
&rect, TRUE);
|
||||
if (aIsSynchronous)
|
||||
gdk_window_process_updates(mDrawingarea->inner_window, TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::InvalidateRegion(const nsIRegion* aRegion,
|
||||
PRBool aIsSynchronous)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
GdkRegion *region = nsnull;
|
||||
aRegion->GetNativeRegion((void *)region);
|
||||
|
||||
gdk_window_invalidate_region(mDrawingarea->inner_window,
|
||||
region, TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -354,7 +395,7 @@ nsWindow::GetNativeData(PRUint32 aDataType)
|
|||
break;
|
||||
|
||||
case NS_NATIVE_PLUGIN_PORT:
|
||||
NS_WARNING("nsWindow::GetNativeData plugin port not supported yet\n");
|
||||
NS_WARNING("nsWindow::GetNativeData plugin port not supported yet");
|
||||
return nsnull;
|
||||
break;
|
||||
|
||||
|
@ -368,7 +409,7 @@ nsWindow::GetNativeData(PRUint32 aDataType)
|
|||
break;
|
||||
|
||||
default:
|
||||
NS_WARNING("nsWindow::GetNativeData called with bad value\n");
|
||||
NS_WARNING("nsWindow::GetNativeData called with bad value");
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
@ -509,6 +550,11 @@ nsWindow::GetAttention()
|
|||
gboolean
|
||||
nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
NS_WARNING("Expose event on destroyed window!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// handle exposes for the inner window only
|
||||
if (aEvent->window != mDrawingarea->inner_window)
|
||||
return FALSE;
|
||||
|
@ -575,6 +621,134 @@ nsWindow::OnDeleteEvent(GtkWidget *aWidget, GdkEventAny *aEvent)
|
|||
DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::OnEnterNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent)
|
||||
{
|
||||
nsMouseEvent event;
|
||||
InitMouseEvent(event, NS_MOUSE_ENTER);
|
||||
|
||||
event.point.x = nscoord(aEvent->x);
|
||||
event.point.y = nscoord(aEvent->y);
|
||||
|
||||
nsEventStatus status;
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::OnLeaveNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent)
|
||||
{
|
||||
nsMouseEvent event;
|
||||
InitMouseEvent(event, NS_MOUSE_EXIT);
|
||||
|
||||
event.point.x = nscoord(aEvent->x);
|
||||
event.point.y = nscoord(aEvent->y);
|
||||
|
||||
nsEventStatus status;
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent)
|
||||
{
|
||||
nsMouseEvent event;
|
||||
InitMouseEvent(event, NS_MOUSE_MOVE);
|
||||
|
||||
event.point.x = nscoord(aEvent->x);
|
||||
event.point.y = nscoord(aEvent->y);
|
||||
|
||||
event.isShift = aEvent->state & GDK_SHIFT_MASK;
|
||||
event.isControl = aEvent->state & GDK_CONTROL_MASK;
|
||||
event.isAlt = aEvent->state & GDK_MOD1_MASK;
|
||||
|
||||
nsEventStatus status;
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::OnButtonPressEvent(GtkWidget *aWidget, GdkEventButton *aEvent)
|
||||
{
|
||||
nsMouseEvent event;
|
||||
PRUint32 eventType;
|
||||
PRBool isWheel;
|
||||
nsEventStatus status;
|
||||
|
||||
// wheel mouse is button 4 or 5
|
||||
isWheel = (aEvent->button == 4 || aEvent->button == 5);
|
||||
|
||||
if (isWheel) {
|
||||
nsMouseScrollEvent scrollEvent;
|
||||
|
||||
InitMouseScrollEvent(scrollEvent, NS_MOUSE_SCROLL);
|
||||
|
||||
if (aEvent->button == 4)
|
||||
scrollEvent.delta = -3;
|
||||
else
|
||||
scrollEvent.delta = -4;
|
||||
|
||||
scrollEvent.point.x = nscoord(aEvent->x);
|
||||
scrollEvent.point.y = nscoord(aEvent->y);
|
||||
|
||||
scrollEvent.isShift = aEvent->state & GDK_SHIFT_MASK;
|
||||
scrollEvent.isControl = aEvent->state & GDK_CONTROL_MASK;
|
||||
scrollEvent.isAlt = aEvent->state & GDK_MOD1_MASK;
|
||||
scrollEvent.isMeta = PR_FALSE; // Gtk+ doesn't have meta
|
||||
|
||||
DispatchEvent(&scrollEvent, status);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aEvent->button) {
|
||||
case 2:
|
||||
eventType = NS_MOUSE_MIDDLE_BUTTON_DOWN;
|
||||
break;
|
||||
case 3:
|
||||
eventType = NS_MOUSE_RIGHT_BUTTON_DOWN;
|
||||
break;
|
||||
default:
|
||||
eventType = NS_MOUSE_LEFT_BUTTON_DOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
InitButtonEvent(event, eventType, aEvent);
|
||||
|
||||
DispatchEvent(&event, status);
|
||||
|
||||
// right menu click on linux should also pop up a context menu
|
||||
if (eventType == NS_MOUSE_RIGHT_BUTTON_DOWN) {
|
||||
InitButtonEvent(event, NS_CONTEXTMENU, aEvent);
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::OnButtonReleaseEvent(GtkWidget *aWidget, GdkEventButton *aEvent)
|
||||
{
|
||||
nsMouseEvent event;
|
||||
PRUint32 eventType;
|
||||
|
||||
switch (aEvent->button) {
|
||||
case 2:
|
||||
eventType = NS_MOUSE_MIDDLE_BUTTON_UP;
|
||||
break;
|
||||
case 3:
|
||||
eventType = NS_MOUSE_RIGHT_BUTTON_UP;
|
||||
break;
|
||||
// don't send events for these types
|
||||
case 4:
|
||||
case 5:
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
eventType = NS_MOUSE_LEFT_BUTTON_UP;
|
||||
break;
|
||||
}
|
||||
|
||||
InitButtonEvent(event, eventType, aEvent);
|
||||
|
||||
nsEventStatus status;
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::SendResizeEvent(nsRect &aRect, nsEventStatus &aStatus)
|
||||
{
|
||||
|
@ -725,6 +899,12 @@ nsWindow::NativeCreate(nsIWidget *aParent,
|
|||
if (mContainer) {
|
||||
g_signal_connect(G_OBJECT(mContainer), "expose_event",
|
||||
G_CALLBACK(expose_event_cb), NULL);
|
||||
g_signal_connect(G_OBJECT(mContainer), "enter_notify_event",
|
||||
G_CALLBACK(enter_notify_event_cb), NULL);
|
||||
g_signal_connect(G_OBJECT(mContainer), "leave_notify_event",
|
||||
G_CALLBACK(leave_notify_event_cb), NULL);
|
||||
g_signal_connect(G_OBJECT(mContainer), "motion_notify_event",
|
||||
G_CALLBACK(motion_notify_event_cb), NULL);
|
||||
|
||||
}
|
||||
|
||||
|
@ -749,7 +929,8 @@ nsWindow::NativeCreate(nsIWidget *aParent,
|
|||
// gtk callbacks
|
||||
|
||||
/* static */
|
||||
gboolean expose_event_cb(GtkWidget *widget, GdkEventExpose *event)
|
||||
gboolean
|
||||
expose_event_cb(GtkWidget *widget, GdkEventExpose *event)
|
||||
{
|
||||
gpointer user_data;
|
||||
user_data = g_object_get_data(G_OBJECT(event->window), "nsWindow");
|
||||
|
@ -795,6 +976,92 @@ delete_event_cb(GtkWidget *widget, GdkEventAny *event)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
gboolean
|
||||
enter_notify_event_cb (GtkWidget *widget,
|
||||
GdkEventCrossing *event)
|
||||
{
|
||||
gpointer user_data;
|
||||
user_data = g_object_get_data(G_OBJECT(event->window), "nsWindow");
|
||||
|
||||
if (!user_data)
|
||||
return TRUE;
|
||||
|
||||
nsWindow *window = NS_STATIC_CAST(nsWindow *, user_data);
|
||||
|
||||
window->OnEnterNotifyEvent(widget, event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/* static */
|
||||
gboolean
|
||||
leave_notify_event_cb (GtkWidget *widget,
|
||||
GdkEventCrossing *event)
|
||||
{
|
||||
gpointer user_data;
|
||||
user_data = g_object_get_data(G_OBJECT(event->window), "nsWindow");
|
||||
|
||||
if (!user_data)
|
||||
return TRUE;
|
||||
|
||||
nsWindow *window = NS_STATIC_CAST(nsWindow *, user_data);
|
||||
|
||||
window->OnLeaveNotifyEvent(widget, event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
gboolean
|
||||
motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event)
|
||||
{
|
||||
gpointer user_data;
|
||||
user_data = g_object_get_data(G_OBJECT(event->window), "nsWindow");
|
||||
|
||||
if (!user_data)
|
||||
return TRUE;
|
||||
|
||||
nsWindow *window = NS_STATIC_CAST(nsWindow *, user_data);
|
||||
|
||||
window->OnMotionNotifyEvent(widget, event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
gboolean
|
||||
button_press_event_cb (GtkWidget *widget, GdkEventButton *event)
|
||||
{
|
||||
gpointer user_data;
|
||||
user_data = g_object_get_data(G_OBJECT(event->window), "nsWindow");
|
||||
|
||||
if (!user_data)
|
||||
return TRUE;
|
||||
|
||||
nsWindow *window = NS_STATIC_CAST(nsWindow *, user_data);
|
||||
|
||||
window->OnButtonPressEvent(widget, event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
gboolean
|
||||
button_release_event_cb (GtkWidget *widget, GdkEventButton *event)
|
||||
{
|
||||
gpointer user_data;
|
||||
user_data = g_object_get_data(G_OBJECT(event->window), "nsWindow");
|
||||
|
||||
if (!user_data)
|
||||
return TRUE;
|
||||
|
||||
nsWindow *window = NS_STATIC_CAST(nsWindow *, user_data);
|
||||
|
||||
window->OnButtonReleaseEvent(widget, event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// nsChildWindow class
|
||||
|
||||
nsChildWindow::nsChildWindow()
|
||||
|
|
|
@ -136,10 +136,20 @@ class nsWindow : public nsCommonWidget {
|
|||
GdkEventExpose *aEvent);
|
||||
gboolean OnConfigureEvent(GtkWidget *aWidget,
|
||||
GdkEventConfigure *aEvent);
|
||||
void SendResizeEvent(nsRect &aRect,
|
||||
nsEventStatus &aStatus);
|
||||
void OnDeleteEvent(GtkWidget *aWidget,
|
||||
GdkEventAny *aEvent);
|
||||
void OnEnterNotifyEvent(GtkWidget *aWidget,
|
||||
GdkEventCrossing *aEvent);
|
||||
void OnLeaveNotifyEvent(GtkWidget *aWidget,
|
||||
GdkEventCrossing *aEvent);
|
||||
void OnMotionNotifyEvent(GtkWidget *aWidget,
|
||||
GdkEventMotion *aEvent);
|
||||
void OnButtonPressEvent(GtkWidget *aWidget,
|
||||
GdkEventButton *aEvent);
|
||||
void OnButtonReleaseEvent(GtkWidget *aWidget,
|
||||
GdkEventButton *aEvent);
|
||||
void SendResizeEvent(nsRect &aRect,
|
||||
nsEventStatus &aStatus);
|
||||
|
||||
private:
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче