fixes for bugs 27790 33649 37003 37004 37257 45499 45761 50009 48276. this is a rewrite of much of the DND code for linux. some of the big features include multiple item drags inside of mozilla, support for _NETSCAPE_URL memory leak fixes and tree scrolling during drags. r=pavlov a=brendan

This commit is contained in:
blizzard%redhat.com 2000-08-31 14:48:14 +00:00
Родитель 2b58c68fab
Коммит 78cb185b89
7 изменённых файлов: 1157 добавлений и 1302 удалений

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

@ -33,32 +33,34 @@ typedef void (*nsIDragSessionGTKTimeCB)(guint32 *aTime);
{ 0xa6b49c42, 0x1dd1, 0x11b2, { 0xb2, 0xdf, 0xc1, 0xd6, 0x1d, 0x67, 0x45, 0xcf } };
class nsIDragSessionGTK : public nsISupports {
public:
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDRAGSESSIONGTK_IID)
NS_IMETHOD SetLastContext (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime) = 0;
NS_IMETHOD StartDragMotion (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime) = 0;
NS_IMETHOD EndDragMotion (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime) = 0;
NS_IMETHOD SetDataReceived (GtkWidget *aWidget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 aTime) = 0;
NS_IMETHOD DataGetSignal (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 aTime,
gpointer data) = 0;
NS_IMETHOD SetTimeCallback (nsIDragSessionGTKTimeCB aCallback) = 0;
// Thse are all target methods - that is when the mozilla is a
// target of a drag. Any methods related to when mozilla starts a
// drag are elsewhere.
// this sets the last drag context used where mozilla is the target
// of a drag
NS_IMETHOD TargetSetLastContext (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime) = 0;
// this is called at the beginning of a drag motion event
NS_IMETHOD TargetStartDragMotion (void) = 0;
// this is called at the end of a drag motion event
NS_IMETHOD TargetEndDragMotion (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime) = 0;
// this is called when data is received after being sent above
NS_IMETHOD TargetDataReceived (GtkWidget *aWidget,
GdkDragContext *aContext,
gint aX,
gint aY,
GtkSelectionData *aSelection_data,
guint aInfo,
guint32 aTime) = 0;
// this sets a callback for time related fun
NS_IMETHOD TargetSetTimeCallback (nsIDragSessionGTKTimeCB aCallback) = 0;
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -43,7 +43,7 @@ public:
// nsIDragService
NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode,
nsISupportsArray * anArrayTransferables,
nsISupportsArray * anArrayTransferables,
nsIScriptableRegion * aRegion,
PRUint32 aActionType);
NS_IMETHOD StartDragSession();
@ -53,67 +53,76 @@ public:
NS_IMETHOD SetCanDrop (PRBool aCanDrop);
NS_IMETHOD GetCanDrop (PRBool *aCanDrop);
NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems);
NS_IMETHOD GetData (nsITransferable * aTransferable, PRUint32 anItemIndex);
NS_IMETHOD GetData (nsITransferable * aTransferable,
PRUint32 aItemIndex);
NS_IMETHOD IsDataFlavorSupported (const char *aDataFlavor, PRBool *_retval);
// nsIDragSessionGTK
NS_IMETHOD SetLastContext (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime);
NS_IMETHOD StartDragMotion (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime);
NS_IMETHOD EndDragMotion (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime);
NS_IMETHOD SetDataReceived (GtkWidget *aWidget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 time);
NS_IMETHOD DataGetSignal (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 time,
gpointer data);
NS_IMETHOD SetTimeCallback (nsIDragSessionGTKTimeCB aCallback);
NS_IMETHOD TargetSetLastContext (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime);
NS_IMETHOD TargetStartDragMotion (void);
NS_IMETHOD TargetEndDragMotion (GtkWidget *aWidget,
GdkDragContext *aContext,
guint aTime);
NS_IMETHOD TargetDataReceived (GtkWidget *aWidget,
GdkDragContext *aContext,
gint aX,
gint aY,
GtkSelectionData *aSelection_data,
guint aInfo,
guint32 aTime);
NS_IMETHOD TargetSetTimeCallback (nsIDragSessionGTKTimeCB aCallback);
// This is called when the drag started with the invisible widget
// finishes. It's called from within the drag service code but from
// a callback - it needs to be public.
void SourceEndDrag(void);
void SourceDataGet(GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 aTime);
// END PUBLIC API
private:
// this is the hidden widget where we get our data
// we start drags from and where we do a grab when we
// are waiting for our DND data back
GtkWidget *mHiddenWidget;
// here's the last drag context
GdkDragContext *mLastContext;
// this is the last widget that had a drag event
GtkWidget *mLastWidget;
// the last time a drag event happened.
guint mLastTime;
// this is the list of data items that we support when we've
// started a drag
nsISupportsArray *mDataItems;
// target side vars
// have we gotten our drag data yet?
PRBool mDataReceived;
// this is where the actual drag data is received
void *mDragData;
PRUint32 mDragDataLen;
// the last widget that was the target of a drag
GtkWidget *mTargetWidget;
GdkDragContext *mTargetDragContext;
guint mTargetTime;
// is it OK to drop on us?
PRBool mCanDrop;
// have we received our drag data?
PRBool mTargetDragDataReceived;
// last data received and its length
void *mTargetDragData;
PRUint32 mTargetDragDataLen;
// is the current target drag context contain a list?
PRBool IsTargetContextList(void);
// this will get the native data from the last target given a
// specific flavor
void GetTargetDragData(GdkAtom aFlavor);
// this will reset all of the target vars
void TargetResetData(void);
// this will reset all of our drag state
void ResetDragState(void);
// set our local data items list and addref it properly
void SetDataItems(nsISupportsArray *anArray);
// get the data for a particular flavor
NS_METHOD GetNativeDragData(GdkAtom aFlavor);
// this is a callback to get the time for the last event that
// happened
// source side vars
// the source of our drags
GtkWidget *mHiddenWidget;
// our source data items
nsCOMPtr<nsISupportsArray> mSourceDataItems;
// get a list of the sources in gtk's format
GtkTargetList *GetSourceList(void);
// this is our callback to get the most recent event's time
nsIDragSessionGTKTimeCB mTimeCB;
};
#endif // nsDragService_h__

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

@ -188,7 +188,7 @@ nsWeakPtr nsWidget::gRollupWidget;
PRBool nsWidget::gRollupConsumeRollupEvent = PR_FALSE;
PRBool nsWidget::mGDKHandlerInstalled = PR_FALSE;
PRBool nsWidget::mTimeCBSet = PR_FALSE;
PRBool nsWidget::sTimeCBSet = PR_FALSE;
#ifdef NS_DEBUG
// debugging window
@ -240,7 +240,6 @@ nsWidget::nsWidget()
mBounds.y = 0;
mBounds.width = 0;
mBounds.height = 0;
mIsDragDest = PR_FALSE;
mIsToplevel = PR_FALSE;
mUpdateArea = do_CreateInstance(kRegionCID);
@ -275,23 +274,20 @@ nsWidget::nsWidget()
// they have been converted to GDK, but before GTK+ gets them
gdk_event_handler_set (handle_gdk_event, NULL, NULL);
}
if (mTimeCBSet == PR_FALSE) {
mTimeCBSet = PR_TRUE;
nsCOMPtr<nsIDragService> dragService;
nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
nsIDragService::GetIID(),
(nsISupports **)&dragService);
if (NS_FAILED(rv)) {
if (sTimeCBSet == PR_FALSE) {
sTimeCBSet = PR_TRUE;
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
if (!dragService) {
g_print("*** warning: failed to get the drag service. this is a _bad_ thing.\n");
mTimeCBSet = PR_FALSE;
sTimeCBSet = PR_FALSE;
}
nsCOMPtr<nsIDragSessionGTK> dragServiceGTK;
dragServiceGTK = do_QueryInterface(dragService);
if (!dragServiceGTK) {
mTimeCBSet = PR_FALSE;
sTimeCBSet = PR_FALSE;
return;
}
dragServiceGTK->SetTimeCallback(nsWidget::GetLastEventTime);
dragServiceGTK->TargetSetTimeCallback(nsWidget::GetLastEventTime);
}
#ifdef NS_DEBUG
// see if we need to set up the debugging window
@ -1232,20 +1228,6 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// Initialize this window instance as a drag target.
gtk_drag_dest_set (mWidget,
(GtkDestDefaults)0,
NULL,
0,
(GdkDragAction)0);
// Drag & Drop events.
InstallDragBeginSignal(mWidget);
InstallDragLeaveSignal(mWidget);
InstallDragMotionSignal(mWidget);
InstallDragDropSignal(mWidget);
InstallDragDataReceived(mWidget);
// Focus
InstallFocusInSignal(mWidget);
InstallFocusOutSignal(mWidget);
@ -1577,56 +1559,6 @@ nsWidget::InstallMotionNotifySignal(GtkWidget * aWidget)
GTK_SIGNAL_FUNC(nsWidget::MotionNotifySignal));
}
void
nsWidget::InstallDragLeaveSignal(GtkWidget * aWidget)
{
NS_ASSERTION( nsnull != aWidget, "widget is null");
InstallSignal(aWidget,
(gchar *)"drag_leave",
GTK_SIGNAL_FUNC(nsWidget::DragLeaveSignal));
}
void
nsWidget::InstallDragMotionSignal(GtkWidget * aWidget)
{
NS_ASSERTION( nsnull != aWidget, "widget is null");
InstallSignal(aWidget,
(gchar *)"drag_motion",
GTK_SIGNAL_FUNC(nsWidget::DragMotionSignal));
}
void
nsWidget::InstallDragBeginSignal(GtkWidget * aWidget)
{
NS_ASSERTION( nsnull != aWidget, "widget is null");
InstallSignal(aWidget,
(gchar *)"drag_begin",
GTK_SIGNAL_FUNC(nsWidget::DragBeginSignal));
}
void
nsWidget::InstallDragDropSignal(GtkWidget * aWidget)
{
NS_ASSERTION( nsnull != aWidget, "widget is null");
InstallSignal(aWidget,
(gchar *)"drag_drop",
GTK_SIGNAL_FUNC(nsWidget::DragDropSignal));
}
void
nsWidget::InstallDragDataReceived(GtkWidget *aWidget)
{
NS_ASSERTION( nsnull != aWidget, "widget is null");
InstallSignal(aWidget,
(gchar *)"drag_data_received",
GTK_SIGNAL_FUNC(nsWidget::DragDataReceivedSignal));
}
//////////////////////////////////////////////////////////////////
void
nsWidget::InstallEnterNotifySignal(GtkWidget * aWidget)
@ -1792,184 +1724,6 @@ nsWidget::OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent)
Release();
}
/* virtual */ void
nsWidget::OnDragMotionSignal(GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint aTime)
{
if (!mIsDragDest)
{
// this will happen on the first motion event, so we will generate an ENTER event
OnDragEnterSignal(aGdkDragContext, x, y, aTime);
}
GtkWidget *source_widget;
source_widget = gtk_drag_get_source_widget (aGdkDragContext);
g_print("motion, source %s\n", source_widget ?
gtk_type_name (GTK_OBJECT (source_widget)->klass->type) :
"unknown");
gdk_drag_status (aGdkDragContext, aGdkDragContext->suggested_action, aTime);
nsMouseEvent event;
event.message = NS_DRAGDROP_OVER;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = this;
event.point.x = x;
event.point.y = y;
AddRef();
DispatchMouseEvent(event);
Release();
}
/* not a real signal.. called from OnDragMotionSignal */
/* virtual */ void
nsWidget::OnDragEnterSignal(GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint aTime)
{
// make sure that we tell the drag manager what the hell is going on.
UpdateDragContext(NULL, aGdkDragContext, aTime);
// we are a drag dest.. cool huh?
mIsDragDest = PR_TRUE;
nsMouseEvent event;
event.message = NS_DRAGDROP_ENTER;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = this;
event.point.x = x;
event.point.y = y;
AddRef();
DispatchMouseEvent(event);
Release();
}
/* virtual */ void
nsWidget::OnDragLeaveSignal(GdkDragContext *context,
guint aTime)
{
// update our drag context
UpdateDragContext(NULL, NULL, aTime);
mIsDragDest = PR_FALSE;
nsMouseEvent event;
event.message = NS_DRAGDROP_EXIT;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = this;
// GdkEvent *current_event;
// current_event = gtk_get_current_event();
// g_print("current event's x_root = %i , y_root = %i\n", current_event->dnd.x_root, current_event->dnd.y_root);
// FIXME
event.point.x = 0;
event.point.y = 0;
AddRef();
DispatchMouseEvent(event);
Release();
}
/* virtual */ void
nsWidget::OnDragBeginSignal(GdkDragContext * aGdkDragContext)
{
nsMouseEvent event;
event.message = NS_MOUSE_MOVE;
event.eventStructType = NS_MOUSE_EVENT;
AddRef();
DispatchMouseEvent(event);
Release();
}
/* virtual */ void
nsWidget::OnDragDropSignal(GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime)
{
UpdateDragContext(aWidget, aDragContext, aTime);
nsMouseEvent event;
event.message = NS_DRAGDROP_DROP;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = this;
event.point.x = x;
event.point.y = y;
AddRef();
DispatchWindowEvent(&event);
Release();
// after a drop takes place we need to make sure that the drag
// service doesn't think that it still has a context. if the other
// way ( besides the drop ) to end a drag event is during the leave
// event and and that case is handled in that handler.
UpdateDragContext(NULL, NULL, 0);
}
/* virtual */
void nsWidget::OnDragDataReceivedSignal(GtkWidget *aWidget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 aTime)
{
// the service is the only one that cares that we get this.
g_print("nsWidget::OnDragDataReceivedSignal\n");
nsCOMPtr<nsIDragService> dragService;
nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
nsIDragService::GetIID(),
(nsISupports **)&dragService);
if (NS_FAILED(rv)) {
g_print("*** warning: failed to get the drag service. this is a _bad_ thing.\n");
return;
}
nsCOMPtr<nsIDragSessionGTK> dragServiceGTK;
dragServiceGTK = do_QueryInterface(dragService);
if (!dragServiceGTK) {
return;
}
dragServiceGTK->SetDataReceived(aWidget, context, x, y, selection_data, info, aTime);
}
//////////////////////////////////////////////////////////////////
/* virtual */ void
nsWidget::OnEnterNotifySignal(GdkEventCrossing * aGdkCrossingEvent)
@ -2482,94 +2236,6 @@ nsWidget::MotionNotifySignal(GtkWidget * aWidget,
return PR_TRUE;
}
/* static */ gint
nsWidget::DragMotionSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime,
void *aData)
{
nsWidget * widget = (nsWidget *) aData;
NS_ASSERTION( nsnull != widget, "instance pointer is null");
widget->OnDragMotionSignal(aDragContext, x, y, aTime);
return PR_TRUE;
}
/* static */ void
nsWidget::DragLeaveSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint aTime,
void *aData)
{
nsWidget * widget = (nsWidget *) aData;
NS_ASSERTION( nsnull != widget, "instance pointer is null");
widget->OnDragLeaveSignal(aDragContext, aTime);
}
/* static */ gint
nsWidget::DragBeginSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime,
void *aData)
{
printf("nsWidget::DragBeginSignal\n");
fflush(stdout);
return PR_TRUE;
}
/* static */ gint
nsWidget::DragDropSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime,
void *aData)
{
NS_ASSERTION( nsnull != aWidget, "widget is null");
NS_ASSERTION( nsnull != aDragContext, "dragcontext is null");
nsWidget * widget = (nsWidget *) aData;
NS_ASSERTION( nsnull != widget, "instance pointer is null");
#if 0
if (widget->DropEvent(aWidget, aDragContext->source_window)) {
return PR_TRUE;
}
#endif
widget->OnDragDropSignal(aWidget, aDragContext, x, y, aTime);
return PR_TRUE;
}
/* static */
void
nsWidget::DragDataReceivedSignal(GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
gpointer aData)
{
NS_ASSERTION(nsnull != aWidget, "widget is null");
NS_ASSERTION(nsnull != aDragContext, "dragcontext is null");
nsWidget *widget = (nsWidget *)aData;
NS_ASSERTION( nsnull != widget, "instance pointer is null");
widget->OnDragDataReceivedSignal(aWidget, aDragContext, x, y, aSelectionData, aInfo, aTime);
}
//////////////////////////////////////////////////////////////////
/* static */ gint
nsWidget::EnterNotifySignal(GtkWidget * aWidget,
@ -2840,7 +2506,7 @@ nsWidget::GetXIC()
if (!mIMEShellWidget) {
mIMEShellWidget = GetShellWidget((GdkWindow*)
GetNativeData(NS_NATIVE_WINDOW));
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
//NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
}
if (!gInputStyle || !gPreeditFontset || !gStatusFontset || !mIMEShellWidget) {
return;
@ -3080,68 +2746,6 @@ GtkWindow *nsWidget::GetTopLevelWindow(void)
return NULL;
}
/* virtual */
void nsWidget::UpdateDragContext(GtkWidget *aWidget, GdkDragContext *aGdkDragContext, guint aTime)
{
// make sure that we tell the drag manager what the hell is going on.
nsCOMPtr<nsIDragService> dragService;
nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
nsIDragService::GetIID(),
(nsISupports **)&dragService);
if (NS_FAILED(rv)) {
g_print("*** warning: failed to get the drag service. this is a _bad_ thing.\n");
return;
}
nsCOMPtr<nsIDragSessionGTK> dragServiceGTK;
dragServiceGTK = do_QueryInterface(dragService);
if (!dragServiceGTK) {
return;
}
dragServiceGTK->SetLastContext(aWidget, aGdkDragContext, aTime);
}
/* virtual */
void nsWidget::StartDragMotion(GtkWidget *aWidget, GdkDragContext *aGdkDragContext, guint aTime)
{
// make sure that we tell the drag manager what the hell is going on.
nsCOMPtr<nsIDragService> dragService;
nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
nsIDragService::GetIID(),
(nsISupports **)&dragService);
if (NS_FAILED(rv)) {
g_print("*** warning: failed to get the drag service. this is a _bad_ thing.\n");
return;
}
nsCOMPtr<nsIDragSessionGTK> dragServiceGTK;
dragServiceGTK = do_QueryInterface(dragService);
if (!dragServiceGTK) {
return;
}
dragServiceGTK->StartDragMotion(aWidget, aGdkDragContext, aTime);
}
/* virtual */
void nsWidget::EndDragMotion(GtkWidget *aWidget, GdkDragContext *aGdkDragContext, guint aTime)
{
// make sure that we tell the drag manager what the hell is going on.
nsCOMPtr<nsIDragService> dragService;
nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
nsIDragService::GetIID(),
(nsISupports **)&dragService);
if (NS_FAILED(rv)) {
g_print("*** warning: failed to get the drag service. this is a _bad_ thing.\n");
return;
}
nsCOMPtr<nsIDragSessionGTK> dragServiceGTK;
dragServiceGTK = do_QueryInterface(dragService);
if (!dragServiceGTK) {
return;
}
dragServiceGTK->EndDragMotion(aWidget, aGdkDragContext, aTime);
}
#ifdef NS_DEBUG
static void setDebugWindow(void)
@ -3332,7 +2936,7 @@ nsWidget::IMESetFocusWidget()
if (!mIMEShellWidget) {
mIMEShellWidget = GetShellWidget((GdkWindow*)
GetNativeData(NS_NATIVE_WINDOW));
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
// NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
if (!mIMEShellWidget) return;
}
if (mIMEShellWidget == this) {
@ -3367,7 +2971,7 @@ nsWidget::IMEActivateWidget()
if (!mIMEShellWidget) {
mIMEShellWidget = GetShellWidget((GdkWindow*)
GetNativeData(NS_NATIVE_WINDOW));
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
//NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
if (!mIMEShellWidget) return;
}
mIMEShellWidget->mIMEIsDeactivating = PR_FALSE;
@ -3379,7 +2983,7 @@ nsWidget::IMEDeactivateWidget()
if (!mIMEShellWidget) {
mIMEShellWidget = GetShellWidget((GdkWindow*)
GetNativeData(NS_NATIVE_WINDOW));
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
//NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
if (!mIMEShellWidget) return;
}
mIMEShellWidget->mIMEIsDeactivating = PR_TRUE;
@ -3446,7 +3050,7 @@ nsWidget::IMECommitEvent(GdkEventKey *aEvent) {
if (!mIMEShellWidget) {
mIMEShellWidget = GetShellWidget((GdkWindow*)
GetNativeData(NS_NATIVE_WINDOW));
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
// NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
if (!mIMEShellWidget) return;
}
nsIMEGtkIC *XIC_tmp = mXIC ? mXIC : mIMEShellWidget->mXIC;
@ -3597,7 +3201,7 @@ void nsWidget::IMECheckPreedit_PreProc()
if (!mIMEShellWidget) {
mIMEShellWidget = GetShellWidget((GdkWindow*)
GetNativeData(NS_NATIVE_WINDOW));
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
// NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
if (!mIMEShellWidget) return;
}
@ -3617,7 +3221,7 @@ void nsWidget::IMECheckPreedit_PostProc()
if (!mIMEShellWidget) {
mIMEShellWidget = GetShellWidget((GdkWindow*)
GetNativeData(NS_NATIVE_WINDOW));
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
//NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
if (!mIMEShellWidget) return;
}
nsIMEGtkIC *XIC_tmp = mXIC ? mXIC : mIMEShellWidget->mXIC;

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

@ -208,10 +208,6 @@ public:
static void GetLastEventTime(guint32 *aTime);
protected:
virtual void UpdateDragContext(GtkWidget *aWidget, GdkDragContext *aGdkDragContext, guint aTime);
virtual void StartDragMotion(GtkWidget *aWidget, GdkDragContext *aGdkDragContext, guint aTime);
virtual void EndDragMotion(GtkWidget *aWidget, GdkDragContext *aGdkDragContext, guint aTime);
virtual void InitCallbacks(char * aName = nsnull);
NS_IMETHOD CreateNative(GtkObject *parentWindow) { return NS_OK; }
@ -254,8 +250,6 @@ public:
protected:
//
PRBool mIsDragDest;
//////////////////////////////////////////////////////////////////
//
@ -264,12 +258,6 @@ protected:
//////////////////////////////////////////////////////////////////
void InstallMotionNotifySignal(GtkWidget * aWidget);
void InstallDragMotionSignal(GtkWidget * aWidget);
void InstallDragLeaveSignal(GtkWidget * aWidget);
void InstallDragBeginSignal(GtkWidget * aWidget);
void InstallDragDropSignal(GtkWidget * aWidget);
void InstallDragDataReceived(GtkWidget * aWidget);
void InstallEnterNotifySignal(GtkWidget * aWidget);
void InstallLeaveNotifySignal(GtkWidget * aWidget);
@ -295,30 +283,6 @@ protected:
//
//////////////////////////////////////////////////////////////////
virtual void OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent);
virtual void OnDragMotionSignal(GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint time);
/* OnDragEnterSignal is not a real signal.. it is only called from OnDragMotionSignal */
virtual void OnDragEnterSignal(GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint time);
virtual void OnDragLeaveSignal(GdkDragContext *context,
guint time);
virtual void OnDragBeginSignal(GdkDragContext *aGdkDragContext);
virtual void OnDragDropSignal(GtkWidget *aWidget,
GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint time);
virtual void OnDragDataReceivedSignal(GtkWidget *aWidget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 time);
virtual void OnEnterNotifySignal(GdkEventCrossing * aGdkCrossingEvent);
virtual void OnLeaveNotifySignal(GdkEventCrossing * aGdkCrossingEvent);
virtual void OnButtonPressSignal(GdkEventButton * aGdkButtonEvent);
@ -403,41 +367,6 @@ protected:
GdkEventMotion * aGdkMotionEvent,
gpointer aData);
static gint DragMotionSignal(GtkWidget * aWidget,
GdkDragContext *context,
gint x,
gint y,
guint time,
void *data);
static void DragLeaveSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint time,
void *aData);
static gint DragBeginSignal(GtkWidget * aWidget,
GdkDragContext *context,
gint x,
gint y,
guint time,
void *data);
static gint DragDropSignal(GtkWidget * aWidget,
GdkDragContext *context,
gint x,
gint y,
guint time,
void *data);
static void DragDataReceivedSignal(GtkWidget *aWidget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 time,
gpointer data);
static gint EnterNotifySignal(GtkWidget * aWidget,
GdkEventCrossing * aGdkCrossingEvent,
gpointer aData);
@ -524,7 +453,7 @@ private:
static PRBool mGDKHandlerInstalled;
// this will keep track of whether or not we've told the drag
// service how to call back into us to get the last event time
static PRBool mTimeCBSet;
static PRBool sTimeCBSet;
//
// Keep track of the last widget being "dragged"

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

@ -54,6 +54,9 @@
#include "nsSpecialSystemDirectory.h"
#include "nsGtkMozRemoteHelper.h"
#include "nsIDragService.h"
#include "nsIDragSessionGTK.h"
#include <unistd.h>
#ifdef NEED_USLEEP_PROTOTYPE
@ -64,6 +67,7 @@ extern "C" int usleep(unsigned int);
#endif
#undef DEBUG_DND_XLATE
#undef DEBUG_DND_EVENTS
#undef DEBUG_FOCUS
#undef DEBUG_GRAB
#define MODAL_TIMERS_BROKEN
@ -76,6 +80,8 @@ extern "C" int usleep(unsigned int);
#define kWindowPositionSlop 10
static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
gint handle_toplevel_focus_in (
GtkWidget * aWidget,
GdkEventFocus * aGdkFocusEvent,
@ -156,6 +162,11 @@ nsWindow::nsWindow()
mLastDragMotionWindow = NULL;
mBlockMozAreaFocusIn = PR_FALSE;
mLastGrabFailed = PR_TRUE;
mDragMotionWidget = 0;
mDragMotionContext = 0;
mDragMotionX = 0;
mDragMotionY = 0;
mDragMotionTime = 0;
}
//-------------------------------------------------------------------------
@ -165,6 +176,9 @@ nsWindow::nsWindow()
//-------------------------------------------------------------------------
nsWindow::~nsWindow()
{
// make sure to unset any drag motion timers here.
ResetDragMotionTimer(0, 0, 0, 0, 0);
// printf("%p nsWindow::~nsWindow\n", this);
// make sure that we release the grab indicator here
if (sGrabWindow == this) {
@ -1370,103 +1384,6 @@ nsWindow::HandleGDKEvent(GdkEvent *event)
}
}
void
nsWindow::InstallToplevelDragDataReceivedSignal(void)
{
NS_ASSERTION( nsnull != mShell, "mShell is null");
InstallSignal(mShell,
(gchar *)"drag_data_received",
GTK_SIGNAL_FUNC(nsWindow::ToplevelDragDataReceivedSignal));
}
/* static */
void nsWindow::ToplevelDragDataReceivedSignal(GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
gpointer aData)
{
nsWindow *widget = (nsWindow *)aData;
NS_ASSERTION(nsnull != widget, "instance pointer is null");
widget->OnDragDataReceivedSignal(aWidget, aDragContext, x, y, aSelectionData, aInfo, aTime);
}
void
nsWindow::InstallToplevelDragBeginSignal(void)
{
NS_ASSERTION( nsnull != mShell, "mShell is null");
InstallSignal(mShell,
(gchar *)"drag_begin",
GTK_SIGNAL_FUNC(nsWindow::ToplevelDragBeginSignal));
}
/* static */
gint
nsWindow::ToplevelDragBeginSignal(GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint time,
void *aData)
{
g_print("nsWindow::ToplevelDragBeginSignal\n");
return PR_FALSE;
}
/* static */
gint
nsWindow::ToplevelDragLeaveSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint aTime,
void *aData)
{
if (mLastDragMotionWindow) {
mLastDragMotionWindow->OnDragLeaveSignal(aDragContext, aTime);
mLastLeaveWindow = mLastDragMotionWindow;
mLastDragMotionWindow = NULL;
}
else {
g_print("Warning: no motion window set\n");
}
return PR_TRUE;
}
void
nsWindow::InstallToplevelDragMotionSignal(void)
{
NS_ASSERTION( nsnull != mShell, "mShell is null");
InstallSignal(mShell,
(gchar *)"drag_motion",
GTK_SIGNAL_FUNC(nsWindow::ToplevelDragMotionSignal));
}
/* static */
gint
nsWindow::ToplevelDragMotionSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint time,
void *aData)
{
nsWindow *widget = (nsWindow *)aData;
NS_ASSERTION(nsnull != widget, "instance pointer is null");
widget->OnToplevelDragMotion(aWidget, aDragContext, x, y, time);
return TRUE;
}
#ifdef NS_DEBUG
/* static */
@ -1571,181 +1488,6 @@ nsWindow::DumpWindowTree(void)
#endif /* NS_DEBUG */
void
nsWindow::OnToplevelDragMotion (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime)
{
#ifdef DEBUG_DND_XLATE
DumpWindowTree();
#endif
nscoord retx = 0;
nscoord rety = 0;
Window thisWindow = GDK_WINDOW_XWINDOW(aWidget->window);
Window returnWindow = None;
returnWindow = GetInnerMostWindow(thisWindow, thisWindow, x, y, &retx, &rety, 0);
nsWindow *innerMostWidget = NULL;
innerMostWidget = GetnsWindowFromXWindow(returnWindow);
if (!innerMostWidget)
innerMostWidget = this;
#ifdef DEBUG_DND_XLATE
g_print("innerMostWidget is %p\n", innerMostWidget);
#endif
// check to see if there was a drag motion window already in place
if (mLastDragMotionWindow) {
// if it wasn't this
if (mLastDragMotionWindow != innerMostWidget) {
// send a drag event to the last window that got a motion event
mLastDragMotionWindow->OnDragLeaveSignal(aDragContext, aTime);
}
}
// set the last window to this
mLastDragMotionWindow = innerMostWidget;
if (!innerMostWidget->mIsDragDest)
{
// this will happen on the first motion event, so we will generate an ENTER event
innerMostWidget->OnDragEnterSignal(aDragContext, x, y, aTime);
}
// notify the drag service that we are starting a drag motion.
StartDragMotion(aWidget, aDragContext, aTime);
nsMouseEvent event;
event.message = NS_DRAGDROP_OVER;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = innerMostWidget;
event.point.x = retx;
event.point.y = rety;
innerMostWidget->AddRef();
innerMostWidget->DispatchMouseEvent(event);
innerMostWidget->Release();
// we're done with the drag motion event. notify the drag service.
EndDragMotion(aWidget, aDragContext, aTime);
}
void
nsWindow::OnToplevelDragDrop (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime)
{
g_print("OnToplevelDragDrop\n");
#ifdef DEBUG_DND_XLATE
DumpWindowTree();
#endif
nscoord retx = 0;
nscoord rety = 0;
Window thisWindow = GDK_WINDOW_XWINDOW(aWidget->window);
Window returnWindow = None;
returnWindow = GetInnerMostWindow(thisWindow, thisWindow, x, y, &retx, &rety, 0);
nsWindow *innerMostWidget = NULL;
innerMostWidget = GetnsWindowFromXWindow(returnWindow);
if (!innerMostWidget)
innerMostWidget = this;
#ifdef DEBUG_DND_XLATE
g_print("innerMostWidget is %p\n", innerMostWidget);
#endif
// check to see if there was a drag motion window already in place
if (mLastDragMotionWindow) {
// if it wasn't this
if (mLastDragMotionWindow != innerMostWidget) {
// send a drag event to the last window that got a motion event
mLastDragMotionWindow->OnDragLeaveSignal(aDragContext, aTime);
}
}
// set the last window to this
mLastDragMotionWindow = innerMostWidget;
if (!innerMostWidget->mIsDragDest)
{
// this will happen on the first motion event, so we will generate an ENTER event
innerMostWidget->OnDragEnterSignal(aDragContext, x, y, aTime);
}
UpdateDragContext(aWidget, aDragContext, aTime);
nsMouseEvent event;
event.message = NS_DRAGDROP_DROP;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = innerMostWidget;
event.point.x = retx;
event.point.y = rety;
innerMostWidget->AddRef();
innerMostWidget->DispatchMouseEvent(event);
innerMostWidget->Release();
// before we unset the context we need to do a drop_finish
gdk_drop_finish(aDragContext, TRUE, aTime);
// after a drop takes place we need to make sure that the drag
// service doesn't think that it still has a context. if the other
// way ( besides the drop ) to end a drag event is during the leave
// event and and that case is handled in that handler.
UpdateDragContext(NULL, NULL, 0);
}
void
nsWindow::InstallToplevelDragDropSignal(void)
{
NS_ASSERTION( nsnull != mShell, "mShell is null");
InstallSignal(mShell,
(gchar *)"drag_drop",
GTK_SIGNAL_FUNC(nsWindow::ToplevelDragDropSignal));
}
/* static */
gint
nsWindow::ToplevelDragDropSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime,
void *aData)
{
nsWindow *widget = (nsWindow *)aData;
NS_ASSERTION(nsnull != widget, "instance pointer is null");
widget->OnToplevelDragDrop(aWidget, aDragContext, x, y, aTime);
return PR_TRUE;
}
void
nsWindow::OnDestroySignal(GtkWidget* aGtkWidget)
{
@ -2026,21 +1768,35 @@ NS_METHOD nsWindow::CreateNative(GtkObject *parentWidget)
gdk_window_set_transient_for(mShell->window, topLevelParent);
}
// install the drag and drop signals for the toplevel window.
InstallToplevelDragBeginSignal();
InstallToplevelDragMotionSignal();
InstallToplevelDragDropSignal();
InstallToplevelDragDataReceivedSignal();
// set up our drag and drop for the shell
gtk_drag_dest_set(mShell,
(GtkDestDefaults)0,
NULL,
0,
(GdkDragAction)0);
// set the shell window as a drop target
gtk_drag_dest_set (mShell,
(GtkDestDefaults)0,
NULL,
0,
(GdkDragAction)0);
gtk_signal_connect(GTK_OBJECT(mShell),
"drag_motion",
GTK_SIGNAL_FUNC(nsWindow::DragMotionSignal),
this);
gtk_signal_connect(GTK_OBJECT(mShell),
"drag_leave",
GTK_SIGNAL_FUNC(nsWindow::DragLeaveSignal),
this);
gtk_signal_connect(GTK_OBJECT(mShell),
"drag_drop",
GTK_SIGNAL_FUNC(nsWindow::DragDropSignal),
this);
gtk_signal_connect(GTK_OBJECT(mShell),
"drag_data_received",
GTK_SIGNAL_FUNC(nsWindow::DragDataReceived),
this);
}
if (mMozArea) {
// add our key event masks so that we can pass events to the inner
// windows.
AddToEventMask(mMozArea, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
gtk_signal_connect(GTK_OBJECT(mMozArea),
"key_press_event",
@ -3209,7 +2965,402 @@ void nsWindow::StoreProperty(char *property, unsigned char *data)
(gint)strlen((char *)data)); /* size of data */
}
// These are all of our drag and drop operations
/* static */
gint
nsWindow::DragMotionSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData)
{
nsWindow *window = (nsWindow *)aData;
return window->OnDragMotionSignal(aWidget, aDragContext, aX, aY, aTime, aData);
}
gint nsWindow::OnDragMotionSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData)
{
#ifdef DEBUG_DND_EVENTS
g_print("nsWindow::OnDragMotionSignal\n");
#endif /* DEBUG_DND_EVENTS */
// Reset out drag motion timer
ResetDragMotionTimer(aWidget, aDragContext, aX, aY, aTime);
// get our drag context
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
nsCOMPtr<nsIDragSessionGTK> dragSessionGTK = do_QueryInterface(dragService);
// first, figure out which internal widget this drag motion actually
// happened on
nscoord retx = 0;
nscoord rety = 0;
Window thisWindow = GDK_WINDOW_XWINDOW(aWidget->window);
Window returnWindow = None;
returnWindow = GetInnerMostWindow(thisWindow, thisWindow, aX, aY,
&retx, &rety, 0);
nsWindow *innerMostWidget = NULL;
innerMostWidget = GetnsWindowFromXWindow(returnWindow);
if (!innerMostWidget)
innerMostWidget = this;
// check to see if there was a drag motion window already in place
if (mLastDragMotionWindow) {
// if it wasn't this
if (mLastDragMotionWindow != innerMostWidget) {
// send a drag event to the last window that got a motion event
mLastDragMotionWindow->OnDragLeave();
// and enter on the new one
innerMostWidget->OnDragEnter(retx, rety);
}
}
else {
// if there was no other motion window, then we're starting a
// drag.
dragService->StartDragSession();
// if there was no other motion window, send an enter event
innerMostWidget->OnDragEnter(retx, rety);
}
// set the last window to the innerMostWidget
mLastDragMotionWindow = innerMostWidget;
// update the drag context
dragSessionGTK->TargetSetLastContext(aWidget, aDragContext, aTime);
// notify the drag service that we are starting a drag motion.
dragSessionGTK->TargetStartDragMotion();
nsMouseEvent event;
event.message = NS_DRAGDROP_OVER;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = innerMostWidget;
event.point.x = retx;
event.point.y = rety;
innerMostWidget->AddRef();
innerMostWidget->DispatchMouseEvent(event);
innerMostWidget->Release();
// we're done with the drag motion event. notify the drag service.
dragSessionGTK->TargetEndDragMotion(aWidget, aDragContext, aTime);
// and unset our context
dragSessionGTK->TargetSetLastContext(0, 0, 0);
return TRUE;
}
/* static */
void
nsWindow::DragLeaveSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint aTime,
gpointer aData)
{
nsWindow *window = (nsWindow *)aData;
window->OnDragLeaveSignal(aWidget, aDragContext, aTime, aData);
}
void
nsWindow::OnDragLeaveSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint aTime,
gpointer aData)
{
#ifdef DEBUG_DND_EVENTS
g_print("nsWindow::OnDragLeaveSignal\n");
#endif /* DEBUG_DND_EVENTS */
// make sure to unset any drag motion timers here.
ResetDragMotionTimer(0, 0, 0, 0, 0);
if (mLastDragMotionWindow) {
// send our leave signal
mLastDragMotionWindow->OnDragLeave();
mLastDragMotionWindow = 0;
// since we're leaving a toplevel window, inform the drag service
// that we're ending the drag
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
dragService->EndDragSession();
}
}
/* static */
gint
nsWindow::DragDropSignal (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData)
{
nsWindow *window = (nsWindow *)aData;
return window->OnDragDropSignal(aWidget, aDragContext, aX, aY, aTime, aData);
}
gint
nsWindow::OnDragDropSignal (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData)
{
#ifdef DEBUG_DND_EVENTS
g_print("nsWindow::OnDragDropSignal\n");
#endif /* DEBUG_DND_EVENTS */
// get our drag context
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
nsCOMPtr<nsIDragSessionGTK> dragSessionGTK = do_QueryInterface(dragService);
nscoord retx = 0;
nscoord rety = 0;
Window thisWindow = GDK_WINDOW_XWINDOW(aWidget->window);
Window returnWindow = None;
returnWindow = GetInnerMostWindow(thisWindow, thisWindow, aX, aY,
&retx, &rety, 0);
nsWindow *innerMostWidget = NULL;
innerMostWidget = GetnsWindowFromXWindow(returnWindow);
// set this now before any of the drag enter or leave events happen
dragSessionGTK->TargetSetLastContext(aWidget, aDragContext, aTime);
if (!innerMostWidget)
innerMostWidget = this;
// check to see if there was a drag motion window already in place
if (mLastDragMotionWindow) {
// if it wasn't this
if (mLastDragMotionWindow != innerMostWidget) {
// send a drag event to the last window that got a motion event
mLastDragMotionWindow->OnDragLeave();
// and enter on the new one
innerMostWidget->OnDragEnter(retx, rety);
}
}
else {
// ok, fire up the drag session so that we think that a drag is in
// progress
dragService->StartDragSession();
// if there was no other motion window, send an enter event
innerMostWidget->OnDragEnter(retx, rety);
}
// set the last window to this
mLastDragMotionWindow = innerMostWidget;
// What we do here is dispatch a new drag motion event to
// re-validate the drag target and then we do the drop. The events
// look the same except for the type.
innerMostWidget->AddRef();
nsMouseEvent event;
event.message = NS_DRAGDROP_OVER;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = innerMostWidget;
event.point.x = retx;
event.point.y = rety;
innerMostWidget->DispatchMouseEvent(event);
event.message = NS_DRAGDROP_DROP;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = innerMostWidget;
event.point.x = retx;
event.point.y = rety;
innerMostWidget->DispatchMouseEvent(event);
innerMostWidget->Release();
// before we unset the context we need to do a drop_finish
gdk_drop_finish(aDragContext, TRUE, aTime);
// after a drop takes place we need to make sure that the drag
// service doesn't think that it still has a context. if the other
// way ( besides the drop ) to end a drag event is during the leave
// event and and that case is handled in that handler.
dragSessionGTK->TargetSetLastContext(0, 0, 0);
// send our drag exit event
innerMostWidget->OnDragLeave();
// and clear the mLastDragMotion window
mLastDragMotionWindow = 0;
// and end our drag session
dragService->EndDragSession();
return TRUE;
}
// when the data has been received
/* static */
void
nsWindow::DragDataReceived (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
gpointer aData)
{
nsWindow *window = (nsWindow *)aData;
window->OnDragDataReceived(aWidget, aDragContext, aX, aY,
aSelectionData, aInfo, aTime, aData);
}
void
nsWindow::OnDragDataReceived (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
gpointer aData)
{
#ifdef DEBUG_DND_EVENTS
g_print("nsWindow::OnDragDataReceived\n");
#endif /* DEBUG_DND_EVENTS */
// get our drag context
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
nsCOMPtr<nsIDragSessionGTK> dragSessionGTK = do_QueryInterface(dragService);
dragSessionGTK->TargetDataReceived(aWidget, aDragContext, aX, aY,
aSelectionData, aInfo, aTime);
}
void
nsWindow::OnDragLeave(void)
{
#ifdef DEBUG_DND_EVENTS
g_print("nsWindow::OnDragLeave\n");
#endif /* DEBUG_DND_EVENTS */
nsMouseEvent event;
event.message = NS_DRAGDROP_EXIT;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = this;
event.point.x = 0;
event.point.y = 0;
AddRef();
DispatchMouseEvent(event);
Release();
}
void
nsWindow::OnDragEnter(nscoord aX, nscoord aY)
{
#ifdef DEBUG_DND_EVENTS
g_print("nsWindow::OnDragEnter\n");
#endif /* DEBUG_DND_EVENTS */
nsMouseEvent event;
event.message = NS_DRAGDROP_ENTER;
event.eventStructType = NS_DRAGDROP_EVENT;
event.widget = this;
event.point.x = aX;
event.point.y = aY;
AddRef();
DispatchMouseEvent(event);
Release();
}
void
nsWindow::ResetDragMotionTimer(GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX, gint aY, guint aTime)
{
// We have to be careful about ref ordering here. if aWidget ==
// mDraMotionWidget be careful not to let the refcnt drop to zero.
// Same with the drag context.
if (aWidget)
gtk_widget_ref(aWidget);
if (mDragMotionWidget)
gtk_widget_unref(mDragMotionWidget);
mDragMotionWidget = aWidget;
if (aDragContext)
gdk_drag_context_ref(aDragContext);
if (mDragMotionContext)
gdk_drag_context_unref(mDragMotionContext);
mDragMotionContext = aDragContext;
mDragMotionX = aX;
mDragMotionY = aY;
mDragMotionTime = aTime;
// clear the timer
if (!aWidget) {
// destroying the timer will cancel it
mDragMotionTimer = 0;
#ifdef DEBUG_DND_EVENTS
g_print("*** canceled motion timer\n");
#endif
return;
}
// otherwise we create a new timer
mDragMotionTimer = do_CreateInstance("component://netscape/timer");
NS_ASSERTION(mDragMotionTimer, "Failed to create drag motion timer!");
mDragMotionTimer->Init(DragMotionTimerCallback, this, 100);
}
void
nsWindow::FireDragMotionTimer(void)
{
#ifdef DEBUG_DND_EVENTS
g_print("nsWindow::FireDragMotionTimer\n");
#endif
OnDragMotionSignal(mDragMotionWidget, mDragMotionContext,
mDragMotionX, mDragMotionY, mDragMotionTime,
this);
}
/* static */
void
nsWindow::DragMotionTimerCallback(nsITimer *aTimer, void *aClosure)
{
nsWindow *window = (nsWindow *)aClosure;
window->FireDragMotionTimer();
}
ChildWindow::ChildWindow()
{

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

@ -103,55 +103,6 @@ public:
virtual void InstallFocusOutSignal(GtkWidget * aWidget);
void HandleGDKEvent(GdkEvent *event);
void InstallToplevelDragBeginSignal (void);
void InstallToplevelDragMotionSignal(void);
void InstallToplevelDragDropSignal (void);
void InstallToplevelDragDataReceivedSignal(void);
static gint ToplevelDragBeginSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime,
void *aData);
static gint ToplevelDragDropSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime,
void *aData);
static gint ToplevelDragLeaveSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint aTime,
void *aData);
static gint ToplevelDragMotionSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime,
void *aData);
static void ToplevelDragDataReceivedSignal(GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
gpointer aData);
void OnToplevelDragMotion (GtkWidget *aWidget,
GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint aTime);
void OnToplevelDragDrop (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint x,
gint y,
guint aTime);
gint ConvertBorderStyles(nsBorderStyle bs);
// Add an XATOM property to this window.
@ -258,10 +209,91 @@ protected:
int depth);
// given an X window this will find the nsWindow * for it.
static nsWindow *GetnsWindowFromXWindow(Window aWindow);
// all of our DND stuff
// this is the last window that had a drag event happen on it.
static nsWindow *mLastDragMotionWindow;
static nsWindow *mLastLeaveWindow;
// DragBegin not needed ?
// always returns TRUE
static gint DragMotionSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData);
gint OnDragMotionSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData);
static void DragLeaveSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint aTime,
gpointer aData);
void OnDragLeaveSignal (GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint aTime,
gpointer aData);
// always returns TRUE
static gint DragDropSignal (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData);
gint OnDragDropSignal (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime,
void *aData);
// when the data has been received
static void DragDataReceived (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
gpointer aData);
void OnDragDataReceived (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
gpointer aData);
// these are drag and drop events that aren't generated by widget
// events but we do synthesize
void OnDragLeave(void);
void OnDragEnter(nscoord aX, nscoord aY);
// this is everything we need to be able to fire motion events
// repeatedly
GtkWidget *mDragMotionWidget;
GdkDragContext *mDragMotionContext;
gint mDragMotionX;
gint mDragMotionY;
guint mDragMotionTime;
nsCOMPtr<nsITimer> mDragMotionTimer;
void ResetDragMotionTimer (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
guint aTime);
void FireDragMotionTimer (void);
static void DragMotionTimerCallback (nsITimer *aTimer, void *aClosure);
#ifdef NS_DEBUG
void DumpWindowTree(void);
static void dumpWindowChildren(Window aWindow, unsigned int depth);