From 3d933328d48454e1c8cfe90c630ab56ec799a336 Mon Sep 17 00:00:00 2001 From: "pavlov%netscape.com" Date: Fri, 17 Dec 1999 23:46:56 +0000 Subject: [PATCH] more work on drag and drop, fix some leaks and make handling of exposes faster and add a little icon so that if you minimize it in some wm's and apps you see the pretty mozilla star logo (icon patch from andersca@swipnet.se) r=blizzard a=chofmann --- widget/src/gtk/minimozicon.xpm | 0 widget/src/gtk/nsDragService.cpp | 41 ++- widget/src/gtk/nsDragService.h | 10 + widget/src/gtk/nsGtkEventHandler.cpp | 30 +- widget/src/gtk/nsWidget.cpp | 84 ++--- widget/src/gtk/nsWidget.h | 9 +- widget/src/gtk/nsWindow.cpp | 461 +++++++++++++++------------ widget/src/gtk/nsWindow.h | 15 +- 8 files changed, 333 insertions(+), 317 deletions(-) create mode 100644 widget/src/gtk/minimozicon.xpm diff --git a/widget/src/gtk/minimozicon.xpm b/widget/src/gtk/minimozicon.xpm new file mode 100644 index 00000000000..e69de29bb2d diff --git a/widget/src/gtk/nsDragService.cpp b/widget/src/gtk/nsDragService.cpp index 9630310c64f..612e31486f6 100644 --- a/widget/src/gtk/nsDragService.cpp +++ b/widget/src/gtk/nsDragService.cpp @@ -93,6 +93,13 @@ NS_IMETHODIMP nsDragService::InvokeDragSession (nsISupportsArray *aTransferableA mWidget = gtk_invisible_new(); gtk_widget_show(mWidget); + gtk_object_set_data(GTK_OBJECT(mWidget), "ds", this); + + // Set up the paste handler: + gtk_signal_connect(GTK_OBJECT(mWidget), "drag_data_received", + GTK_SIGNAL_FUNC(nsDragService::SelectionReceivedCB), + nsnull); + // add the flavors from the transferables. Cache this array for the send data proc GtkTargetList *targetlist = RegisterDragItemsAndFlavors(aTransferableArray); @@ -222,7 +229,7 @@ nsDragService::RegisterDragItemsAndFlavors(nsISupportsArray *inArray) PRBool nsDragService::DoConvert(GdkAtom type) { - g_print("nsDragService::DoRealConvert(%li)\n {\n", type); + g_print("nsDragService::DoConvert(%li)\n {\n", type); int e = 0; // Set a flag saying that we're blocking waiting for the callback: mBlocking = PR_TRUE; @@ -243,7 +250,7 @@ PRBool nsDragService::DoConvert(GdkAtom type) #ifdef DEBUG_DRAG printf(" Waiting for the callback... mBlocking = %d\n", mBlocking); #endif /* DEBUG_CLIPBOARD */ - for (e=0; mBlocking == PR_TRUE && e < 1000; ++e) + for (e=0; mBlocking == PR_TRUE && e < 5; ++e) { gtk_main_iteration_do(PR_TRUE); } @@ -258,8 +265,6 @@ PRBool nsDragService::DoConvert(GdkAtom type) return PR_FALSE; } -#if 0 - /** * Called when the data from a drag comes in (recieved from gdk_selection_convert) * @@ -279,9 +284,9 @@ nsDragService::SelectionReceivedCB (GtkWidget *aWidget, #ifdef DEBUG_DRAG printf(" nsDragService::SelectionReceivedCB\n {\n"); #endif - nsDragService *ds =(nsDragSession *)gtk_object_get_data(GTK_OBJECT(aWidget), - "ds"); - if (!cb) + nsDragService *ds =(nsDragService *)gtk_object_get_data(GTK_OBJECT(aWidget), + "ds"); + if (!ds) { g_print("no dragservice found.. this is bad.\n"); return; @@ -296,14 +301,14 @@ nsDragService::SelectionReceivedCB (GtkWidget *aWidget, /** - * local method (called from nsClipboard::SelectionReceivedCB) + * local method (called from nsDragService::SelectionReceivedCB) * * @param aWidget the widget * @param aSelectionData gtk selection stuff */ void nsDragService::SelectionReceiver (GtkWidget *aWidget, - GtkSelectionData *aSD) + GtkSelectionData *aSD) { gint type; @@ -318,7 +323,7 @@ nsDragService::SelectionReceiver (GtkWidget *aWidget, return; } - +#if 0 switch (type) { case GDK_TARGET_STRING: @@ -345,6 +350,7 @@ nsDragService::SelectionReceiver (GtkWidget *aWidget, return; default: +#endif mSelectionData = *aSD; mSelectionData.data = g_new(guchar, aSD->length + 1); memcpy(mSelectionData.data, @@ -352,16 +358,17 @@ nsDragService::SelectionReceiver (GtkWidget *aWidget, aSD->length); mSelectionData.length = aSD->length; return; +#if 0 } +#endif } -#endif //------------------------------------------------------------------------- NS_IMETHODIMP nsDragService::GetNumDropItems (PRUint32 * aNumItems) { g_print("nsDragService::GetNumDropItems\n"); - *aNumItems = 0; + *aNumItems = 1; return NS_OK; } @@ -370,7 +377,7 @@ NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32 { #ifdef DEBUG_DRAG - printf("nsClipboard::GetNativeClipboardData()\n"); + printf("nsDragService::GetData()\n"); #endif /* DEBUG_CLIPBOARD */ // make sure we have a good transferable @@ -397,7 +404,7 @@ NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32 if ( currentFlavor ) { nsXPIDLCString flavorStr; currentFlavor->ToString(getter_Copies(flavorStr)); - if (DoConvert(gdk_atom_intern(flavorStr, 1))) { + if (DoConvert(gdk_atom_intern(flavorStr, FALSE))) { foundFlavor = flavorStr; break; } @@ -426,7 +433,9 @@ NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32 #endif nsCOMPtr genericDataWrapper; - nsPrimitiveHelpers::CreatePrimitiveForData ( foundFlavor, mSelectionData.data, mSelectionData.length, getter_AddRefs(genericDataWrapper) ); + nsPrimitiveHelpers::CreatePrimitiveForData ( foundFlavor, + mSelectionData.data, + mSelectionData.length, getter_AddRefs(genericDataWrapper) ); aTransferable->SetTransferData(foundFlavor, genericDataWrapper, mSelectionData.length); @@ -533,7 +542,7 @@ nsDragService::DragDrop(GtkWidget *widget, g_print("drop\n"); //gHaveDrag = PR_FALSE; - if (context->targets){ + if (context->targets) { gtk_drag_get_data (widget, context, GPOINTER_TO_INT (context->targets->data), time); diff --git a/widget/src/gtk/nsDragService.h b/widget/src/gtk/nsDragService.h index c2f870eb55e..0d1e141990a 100644 --- a/widget/src/gtk/nsDragService.h +++ b/widget/src/gtk/nsDragService.h @@ -58,6 +58,16 @@ public: protected: + void SelectionReceivedCB (GtkWidget *aWidget, + GdkDragContext *aContext, + gint aX, + gint aY, + GtkSelectionData *aSelectionData, + guint aInfo, + guint aTime); + void SelectionReceiver (GtkWidget *aWidget, GtkSelectionData *aSD); + + PRBool DoConvert(GdkAtom type); static PRBool gHaveDrag; diff --git a/widget/src/gtk/nsGtkEventHandler.cpp b/widget/src/gtk/nsGtkEventHandler.cpp index 3f1e488ace3..f443b5b475e 100644 --- a/widget/src/gtk/nsGtkEventHandler.cpp +++ b/widget/src/gtk/nsGtkEventHandler.cpp @@ -372,7 +372,7 @@ void InitKeyPressEvent(GdkEventKey *aGEK, } else anEvent.keyCode = nsPlatformToDOMKeyCode(aGEK); -#if defined(DEBUG_akkana_not) || defined(DEBUG_pavlov) || defined (DEBUG_ftang) +#if defined(DEBUG_akkana_not) || defined (DEBUG_ftang) printf("Key Press event: keyCode = 0x%x, char code = '%c'", anEvent.keyCode, anEvent.charCode); if (anEvent.isShift) @@ -411,9 +411,9 @@ void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p) nsSizeEvent event; InitAllocationEvent(alloc, p, event, NS_SIZE); - NS_ADDREF(widget); + NS_ADDREF(NS_STATIC_CAST(nsIWidget*,widget)); widget->OnResize(event); - NS_RELEASE(widget); + NS_RELEASE(NS_STATIC_CAST(nsIWidget*,widget)); delete event.windowSize; } @@ -427,9 +427,9 @@ gint handle_expose_event(GtkWidget *w, GdkEventExpose *event, gpointer p) InitExposeEvent(event, p, pevent, NS_PAINT); nsWindow *win = (nsWindow *)p; - win->AddRef(); + NS_ADDREF(NS_STATIC_CAST(nsIWidget*,win)); win->OnExpose(pevent); - win->Release(); + NS_RELEASE(NS_STATIC_CAST(nsIWidget*,win)); UninitExposeEvent(event, p, pevent, NS_PAINT); @@ -533,9 +533,9 @@ void handle_scrollbar_value_changed(GtkAdjustment *adj, gpointer p) GdkWindow *win = (GdkWindow *)widget->GetNativeData(NS_NATIVE_WINDOW); gdk_window_get_pointer(win, &sevent.point.x, &sevent.point.y, nsnull); - widget->AddRef(); + NS_ADDREF(NS_STATIC_CAST(nsIWidget*,widget)); widget->OnScroll(sevent, adj->value); - widget->Release(); + NS_RELEASE(NS_STATIC_CAST(nsIWidget*,widget)); /* FIXME we need to set point.* from the event stuff. */ #if 0 @@ -689,7 +689,7 @@ gint handle_key_press_event_for_text(GtkObject *w, GdkEventKey* event, || event->keyval == GDK_Control_R) return PR_TRUE; - win->AddRef(); + NS_ADDREF(NS_STATIC_CAST(nsIWidget*,win)); InitKeyEvent(event, p, kevent, NS_KEY_DOWN); win->OnKey(kevent); @@ -701,7 +701,7 @@ gint handle_key_press_event_for_text(GtkObject *w, GdkEventKey* event, InitKeyPressEvent(event,p, kevent); win->OnKey(kevent); - win->Release(); + NS_RELEASE(NS_STATIC_CAST(nsIWidget*,win)); if (w) { gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event"); @@ -725,9 +725,9 @@ gint handle_key_release_event_for_text(GtkObject *w, GdkEventKey* event, return PR_TRUE; InitKeyEvent(event, p, kevent, NS_KEY_UP); - win->AddRef(); + NS_ADDREF(NS_STATIC_CAST(nsIWidget*,win)); win->OnKey(kevent); - win->Release(); + NS_RELEASE(NS_STATIC_CAST(nsIWidget*,win)); if (w) { @@ -757,7 +757,7 @@ gint handle_key_press_event(GtkObject *w, GdkEventKey* event, gpointer p) || event->keyval == GDK_Control_R) return PR_TRUE; - win->AddRef(); + NS_ADDREF(NS_STATIC_CAST(nsIWidget*,win)); // // First, dispatch the Key event as a virtual key down event // @@ -793,7 +793,7 @@ gint handle_key_press_event(GtkObject *w, GdkEventKey* event, gpointer p) win->OnKey(kevent); } - win->Release(); + NS_RELEASE(NS_STATIC_CAST(nsIWidget*,win)); if (w) { gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event"); @@ -816,9 +816,9 @@ gint handle_key_release_event(GtkObject *w, GdkEventKey* event, gpointer p) InitKeyEvent(event, p, kevent, NS_KEY_UP); nsWindow * win = (nsWindow *) p; - win->AddRef(); + NS_ADDREF(NS_STATIC_CAST(nsIWidget*,win)); win->OnKey(kevent); - win->Release(); + NS_RELEASE(NS_STATIC_CAST(nsIWidget*,win)); if (w) { diff --git a/widget/src/gtk/nsWidget.cpp b/widget/src/gtk/nsWidget.cpp index a542e9cdcb7..9c251d680e4 100644 --- a/widget/src/gtk/nsWidget.cpp +++ b/widget/src/gtk/nsWidget.cpp @@ -190,7 +190,7 @@ static guint n_targets = sizeof(target_table) / sizeof(target_table[0]); nsWidget::nsWidget() { // XXX Shouldn't this be done in nsBaseWidget? - NS_INIT_REFCNT(); + // NS_INIT_REFCNT(); if (!sLookAndFeel) { if (NS_OK != nsComponentManager::CreateInstance(kLookAndFeelCID, @@ -292,48 +292,7 @@ nsWidget::~nsWidget() // nsISupport stuff // //------------------------------------------------------------------------- -NS_IMPL_ADDREF(nsWidget) -NS_IMPL_RELEASE(nsWidget) -NS_IMETHODIMP nsWidget::QueryInterface(const nsIID& aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - if (aIID.Equals(nsIKBStateControl::GetIID())) { - *aInstancePtr = (void*) ((nsIKBStateControl*)this); - NS_ADDREF((nsBaseWidget*)this); - return NS_OK; - } - - return nsBaseWidget::QueryInterface(aIID,aInstancePtr); -} - -NS_IMETHODIMP nsWidget::GetAbsoluteBounds(nsRect &aRect) -{ - gint x; - gint y; - -#ifdef DEBUG_pavlov - g_print("nsWidget::GetAbsoluteBounds\n"); -#endif - if (mWidget) - { - if (mWidget->window) - { - gdk_window_get_origin(mWidget->window, &x, &y); - aRect.x = x; - aRect.y = y; -#ifdef DEBUG_pavlov - g_print(" x = %i, y = %i\n", x, y); -#endif - } - else - return NS_ERROR_FAILURE; - } - - return NS_OK; -} +NS_IMPL_ISUPPORTS_INHERITED(nsWidget, nsBaseWidget, nsIKBStateControl) NS_IMETHODIMP nsWidget::WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect) { @@ -369,9 +328,9 @@ void nsWidget::IndentByDepth(FILE* out) { PRInt32 depth = 0; - nsWidget* parent = (nsWidget*)mParent; + nsWidget* parent = (nsWidget*)mParent.get(); while (parent) { - parent = (nsWidget*) parent->mParent; + parent = (nsWidget*) parent->mParent.get(); depth++; } while (--depth >= 0) fprintf(out, " "); @@ -386,7 +345,7 @@ nsWidget::IndentByDepth(FILE* out) NS_IMETHODIMP nsWidget::Destroy(void) { - + // printf("%p nsWidget::Destroy()\n", this); // make sure we don't call this more than once. if (mIsDestroying) return NS_OK; @@ -398,9 +357,6 @@ NS_IMETHODIMP nsWidget::Destroy(void) // are released nsBaseWidget::Destroy(); - // release our parent - NS_IF_RELEASE(mParent); - // destroy our native windows DestroyNative(); @@ -468,10 +424,10 @@ nsWidget::OnDestroySignal(GtkWidget* aGtkWidget) nsIWidget* nsWidget::GetParent(void) { - if (mParent) { - NS_ADDREF(mParent); - } - return mParent; + nsIWidget *ret; + ret = mParent; + NS_IF_ADDREF(ret); + return ret; } //------------------------------------------------------------------------- @@ -1106,10 +1062,11 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent, (aInitData->mWindowType == eWindowType_dialog || aInitData->mWindowType == eWindowType_toplevel) ? nsnull : aParent; + BaseCreate(baseParent, aRect, aHandleEventFunction, aContext, aAppShell, aToolkit, aInitData); + mParent = aParent; - NS_IF_ADDREF(mParent); if (aNativeParent) { parentWidget = GTK_OBJECT(aNativeParent); @@ -1687,12 +1644,12 @@ nsWidget::OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent) nsWidget::OnDragMotionSignal(GdkDragContext *aGdkDragContext, gint x, gint y, - guint time) + guint aTime) { if (!mIsDragDest) { // this will happen on the first motion event, so we will generate an ENTER event - OnDragEnterSignal(aGdkDragContext, x, y, time); + OnDragEnterSignal(aGdkDragContext, x, y, aTime); } @@ -1702,9 +1659,7 @@ nsWidget::OnDragMotionSignal(GdkDragContext *aGdkDragContext, gtk_type_name (GTK_OBJECT (source_widget)->klass->type) : "unknown"); - gdk_drag_status (aGdkDragContext, aGdkDragContext->suggested_action, time); - - + gdk_drag_status (aGdkDragContext, aGdkDragContext->suggested_action, aTime); nsMouseEvent event; @@ -1728,7 +1683,7 @@ nsWidget::OnDragMotionSignal(GdkDragContext *aGdkDragContext, nsWidget::OnDragEnterSignal(GdkDragContext *aGdkDragContext, gint x, gint y, - guint time) + guint aTime) { // we are a drag dest.. cool huh? mIsDragDest = PR_TRUE; @@ -1752,7 +1707,7 @@ nsWidget::OnDragEnterSignal(GdkDragContext *aGdkDragContext, /* virtual */ void nsWidget::OnDragLeaveSignal(GdkDragContext *context, - guint time) + guint aTime) { mIsDragDest = PR_FALSE; @@ -1800,7 +1755,7 @@ nsWidget::OnDragBeginSignal(GdkDragContext * aGdkDragContext) nsWidget::OnDragDropSignal(GdkDragContext *aDragContext, gint x, gint y, - guint time) + guint aTime) { nsMouseEvent event; @@ -1808,9 +1763,8 @@ nsWidget::OnDragDropSignal(GdkDragContext *aDragContext, event.eventStructType = NS_DRAGDROP_EVENT; event.widget = this; - // Test coordinates. - event.point.x = 17; - event.point.y = 19; + event.point.x = x; + event.point.y = y; AddRef(); diff --git a/widget/src/gtk/nsWidget.h b/widget/src/gtk/nsWidget.h index a2173ef9125..c4d3679edcc 100644 --- a/widget/src/gtk/nsWidget.h +++ b/widget/src/gtk/nsWidget.h @@ -41,6 +41,7 @@ class nsIToolkit; #include "gtkmozbox.h" #include "nsITimer.h" +#include "nsITimerCallback.h" #define NSRECT_TO_GDKRECT(ns,gdk) \ PR_BEGIN_MACRO \ @@ -70,10 +71,7 @@ public: nsWidget(); virtual ~nsWidget(); - // nsISupports - NS_IMETHOD_(nsrefcnt) AddRef(void); - NS_IMETHOD_(nsrefcnt) Release(void); - NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + NS_DECL_ISUPPORTS_INHERITED // nsIWidget @@ -126,7 +124,6 @@ public: void* GetNativeData(PRUint32 aDataType); - NS_IMETHOD GetAbsoluteBounds(nsRect &aRect); NS_IMETHOD WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect); NS_IMETHOD ScreenToWidget(const nsRect &aOldRect, nsRect &aNewRect); @@ -401,7 +398,7 @@ protected: // our mozbox for those native widgets GtkWidget *mMozBox; - nsIWidget *mParent; + nsCOMPtr mParent; // This is the composite update area (union of all the calls to // Invalidate) diff --git a/widget/src/gtk/nsWindow.cpp b/widget/src/gtk/nsWindow.cpp index db18bf86cfb..de9d1ca3d04 100644 --- a/widget/src/gtk/nsWindow.cpp +++ b/widget/src/gtk/nsWindow.cpp @@ -102,6 +102,9 @@ static GtkTargetEntry target_table[] = { static guint n_targets = sizeof(target_table) / sizeof(target_table[0]); + +NS_IMPL_ISUPPORTS_INHERITED(nsWindow, nsWidget, nsITimerCallback) + //------------------------------------------------------------------------- // // nsWindow constructor @@ -109,7 +112,7 @@ static guint n_targets = sizeof(target_table) / sizeof(target_table[0]); //------------------------------------------------------------------------- nsWindow::nsWindow() { - NS_INIT_REFCNT(); + // NS_INIT_REFCNT(); mFontMetrics = nsnull; mShell = nsnull; mResized = PR_FALSE; @@ -126,6 +129,7 @@ nsWindow::nsWindow() mIsTooSmall = PR_FALSE; mIsUpdating = PR_FALSE; mBlockFocusEvents = PR_FALSE; + mExposeTimer = nsnull; // init the hash table if it hasn't happened already if (mWindowLookupTable == NULL) { mWindowLookupTable = g_hash_table_new(g_int_hash, g_int_equal); @@ -143,7 +147,7 @@ nsWindow::nsWindow() //------------------------------------------------------------------------- nsWindow::~nsWindow() { - + // printf("%p nsWindow::~nsWindow\n", this); // make sure that we release the grab indicator here if (mGrabWindow == this) { mIsGrabbing = PR_FALSE; @@ -242,16 +246,19 @@ nsWindow::DestroyNative(void) void nsWindow::DestroyNativeChildren(void) { + nsCOMPtr children (getter_AddRefs(GetChildren())); if (children) { children->First(); do { - nsISupports *child; - if (NS_SUCCEEDED(children->CurrentItem(&child))) { - nsIWidget *childWindow = NS_STATIC_CAST(nsIWidget *, child); - NS_RELEASE(child); + nsCOMPtr child; + if (NS_SUCCEEDED(children->CurrentItem(getter_AddRefs(child)))) { + nsCOMPtr childWindow = do_QueryInterface(child); childWindow->Destroy(); + // only one of these should be on at a time... + // printf("destroying child ref=%i\n", childWindow->Release()); + NS_RELEASE(childWindow); } } while(NS_SUCCEEDED(children->Next())); } @@ -483,22 +490,6 @@ nsWindow::UnqueueDraw () } } -NS_IMETHODIMP nsWindow::GetAbsoluteBounds(nsRect &aRect) -{ - gint x; - gint y; - - if (mSuperWin) - { - gdk_window_get_origin(mSuperWin->shell_window, &x, &y); - aRect.x = x; - aRect.y = y; - } - else - return NS_ERROR_FAILURE; - return NS_OK; -} - void nsWindow::DoPaint (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, nsIRegion *aClipRegion) @@ -540,35 +531,35 @@ nsWindow::DoPaint (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, event.renderingContext->SetClipRect(clipRect, nsClipCombine_kReplace, rv); } - #ifdef NS_DEBUG - if (WANT_PAINT_FLASHING) - { - GdkWindow *gw = GetRenderWindow(GTK_OBJECT(mSuperWin)); - if (gw) + if (WANT_PAINT_FLASHING) { - GdkRectangle ar; - GdkRectangle * area = (GdkRectangle*) NULL; - - if (event.rect) + GdkWindow *gw = GetRenderWindow(GTK_OBJECT(mSuperWin)); + if (gw) { - ar.x = event.rect->x; - ar.y = event.rect->y; - - ar.width = event.rect->width; - ar.height = event.rect->height; - - area = &ar; - } + GdkRectangle ar; + GdkRectangle * area = (GdkRectangle*) NULL; - nsGtkUtils::gdk_window_flash(gw,1,100000,area); + if (event.rect) + { + ar.x = event.rect->x; + ar.y = event.rect->y; + + ar.width = event.rect->width; + ar.height = event.rect->height; + + area = &ar; + } + + nsGtkUtils::gdk_window_flash(gw,1,100000,area); + } } - } #endif // NS_DEBUG DispatchWindowEvent(&event); NS_RELEASE(event.renderingContext); } + } } @@ -616,9 +607,6 @@ NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent) { -#ifdef DEBUG_pavlov - printf("nsWindow::CaptureRollupEvents() this = %p , doCapture = %i\n", this, aDoCapture); -#endif GtkWidget *grabWidget; grabWidget = mWidget; @@ -626,35 +614,21 @@ NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener * aListener, if (aDoCapture) { -#ifdef DEBUG_pavlov - printf("grabbing widget\n"); -#endif GdkCursor *cursor = gdk_cursor_new (GDK_ARROW); if (!mSuperWin) { -#ifdef DEBUG_pavlov - printf("no superWin for this widget"); -#endif - } - else - { - mIsGrabbing = PR_TRUE; - mGrabWindow = this; -#ifdef DEBUG_pavlov - int ret = -#endif - gdk_pointer_grab (GDK_SUPERWIN(mSuperWin)->bin_window, PR_TRUE,(GdkEventMask) - (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | - GDK_POINTER_MOTION_MASK), - (GdkWindow*)NULL, cursor, GDK_CURRENT_TIME); -#ifdef DEBUG_pavlov - printf("pointer grab returned %i\n", ret); -#endif + } else { + mIsGrabbing = PR_TRUE; + mGrabWindow = this; + + gdk_pointer_grab (GDK_SUPERWIN(mSuperWin)->bin_window, PR_TRUE,(GdkEventMask) + (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK), + (GdkWindow*)NULL, cursor, GDK_CURRENT_TIME); + gdk_cursor_destroy(cursor); } - } - else - { + } else { #ifdef DEBUG_pavlov printf("ungrabbing widget\n"); #endif @@ -675,7 +649,7 @@ NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener * aListener, gRollupListener = aListener; NS_ADDREF(aListener); gRollupWidget = this; - NS_ADDREF(this); + NS_ADDREF(gRollupWidget); } else { // gtk_grab_remove(mWidget); NS_IF_RELEASE(gRollupListener); @@ -1800,10 +1774,14 @@ NS_IMETHODIMP nsWindow::SetTitle(const nsString& aTitle) // Just give the window a default icon, Mozilla. #include "mozicon50.xpm" +#include "minimozicon.xpm" + nsresult nsWindow::SetIcon() { static GdkPixmap *w_pixmap = nsnull; static GdkBitmap *w_mask = nsnull; + static GdkPixmap *w_minipixmap = nsnull; + static GdkBitmap *w_minimask = nsnull; GtkStyle *w_style; w_style = gtk_widget_get_style (mShell); @@ -1815,10 +1793,40 @@ nsresult nsWindow::SetIcon() &w_style->bg[GTK_STATE_NORMAL], mozicon50_xpm); } - - return SetIcon(w_pixmap, w_mask); + + if (!w_minipixmap) { + w_minipixmap = + gdk_pixmap_create_from_xpm_d (mShell->window, + &w_minimask, + &w_style->bg[GTK_STATE_NORMAL], + minimozicon_xpm); + } + + if (SetIcon(w_pixmap, w_mask) != NS_OK) + return NS_ERROR_FAILURE; + + /* Now set the mini icon */ + return SetMiniIcon (w_minipixmap, w_minimask); } +nsresult nsWindow::SetMiniIcon(GdkPixmap *pixmap, + GdkBitmap *mask) +{ + GdkAtom icon_atom; + glong data[2]; + + if (!mShell) + return NS_ERROR_FAILURE; + + data[0] = ((GdkPixmapPrivate *)pixmap)->xwindow; + data[1] = ((GdkPixmapPrivate *)mask)->xwindow; + + icon_atom = gdk_atom_intern ("KWM_WIN_ICON", FALSE); + gdk_property_change (mShell->window, icon_atom, icon_atom, + 32, GDK_PROP_MODE_REPLACE, + (guchar *)data, 2); + return NS_OK; +} // Set the iconify icon for the window. nsresult nsWindow::SetIcon(GdkPixmap *pixmap, @@ -1832,108 +1840,140 @@ nsresult nsWindow::SetIcon(GdkPixmap *pixmap, return NS_OK; } + + +void nsWindow::Notify(nsITimer* aTimer) +{ + // printf("%p nsWindow::Notify()\n", this); + mUpdateArea->Intersect(0, 0, mBounds.width, mBounds.height); + +#if 0 + + // NS_ADDREF(mUpdateArea); + // event.region = mUpdateArea; + if (mScrollExposeCounter > 1) { + //printf("mScrollExposeCounter-- = %i\n", mScrollExposeCounter); + mScrollExposeCounter--; + return NS_OK; + } + + // printf("mScrollExposeCounter = 0\n"); + mScrollExposeCounter = 0; + +#endif + + nsPaintEvent event; + + event.rect = new nsRect(); + + event.message = NS_PAINT; + event.widget = this; + event.eventStructType = NS_PAINT_EVENT; + // event.point.x = event->xexpose.x; + // event.point.y = event->xexpose.y; + /* XXX fix this */ + event.time = 0; + + // printf("\n\n"); + PRInt32 x, y, w, h; + mUpdateArea->GetBoundingBox(&x,&y,&w,&h); + + // printf("\n\n"); + event.rect->x = x; + event.rect->y = y; + event.rect->width = w; + event.rect->height = h; + + if (event.rect->width == 0 || event.rect->height == 0) + { + //printf("********\n****** got an expose for 0x0 window?? - ignoring paint for 0x0\n"); + NS_RELEASE(aTimer); + mExposeTimer = nsnull; + return; + } + + // print out stuff here incase the event got dropped on the floor above +#ifdef NS_DEBUG + if (CAPS_LOCK_IS_ON) + { + debug_DumpPaintEvent(stdout, + this, + &event, + debug_GetName(GTK_OBJECT(mSuperWin)), + (PRInt32) debug_GetRenderXID(GTK_OBJECT(mSuperWin))); + } +#endif // NS_DEBUG + + event.renderingContext = GetRenderingContext(); + if (event.renderingContext) + { + PRBool rv; + + event.renderingContext->SetClipRegion(NS_STATIC_CAST(const nsIRegion &, *mUpdateArea), + nsClipCombine_kReplace, rv); + + DispatchWindowEvent(&event); + NS_RELEASE(event.renderingContext); + // NS_RELEASE(mUpdateArea); + } + + + mUpdateArea->Subtract(event.rect->x, event.rect->y, event.rect->width, event.rect->height); + +#ifdef NS_DEBUG + if (WANT_PAINT_FLASHING) + { + GdkWindow *gw = GetRenderWindow(GTK_OBJECT(mSuperWin)); + if (gw) + { + GdkRectangle ar; + GdkRectangle * area = (GdkRectangle*) NULL; + + if (event.rect) + { + ar.x = event.rect->x; + ar.y = event.rect->y; + + ar.width = event.rect->width; + ar.height = event.rect->height; + + area = &ar; + } + + nsGtkUtils::gdk_window_flash(gw,1,100000,area); + } + } +#endif // NS_DEBUG + + NS_RELEASE(aTimer); + mExposeTimer = nsnull; +} + + /** * Processes an Expose Event * **/ PRBool nsWindow::OnExpose(nsPaintEvent &event) { - nsresult result; + nsresult result = PR_TRUE; // call the event callback if (mEventCallback) { event.renderingContext = nsnull; + // printf("nsWindow::OnExpose\n"); + // expose.. we didn't get an Invalidate, so we should up the count here mUpdateArea->Union(event.rect->x, event.rect->y, event.rect->width, event.rect->height); - mUpdateArea->Intersect(0, 0, mBounds.width, mBounds.height); - -#if 0 - - // NS_ADDREF(mUpdateArea); - // event.region = mUpdateArea; - if (mScrollExposeCounter > 1) { - //printf("mScrollExposeCounter-- = %i\n", mScrollExposeCounter); - mScrollExposeCounter--; - return NS_OK; + if (!mExposeTimer) { + if (NS_NewTimer(&mExposeTimer) == NS_OK) + mExposeTimer->Init(this, 15); } - -#endif - - // printf("mScrollExposeCounter = 0\n"); - mScrollExposeCounter = 0; - - // printf("\n\n"); - PRInt32 x, y, w, h; - mUpdateArea->GetBoundingBox(&x,&y,&w,&h); - - // printf("\n\n"); - event.rect->x = x; - event.rect->y = y; - event.rect->width = w; - event.rect->height = h; - - if (event.rect->width == 0 || event.rect->height == 0) - { - // printf("********\n****** got an expose for 0x0 window?? - ignoring paint for 0x0\n"); - return NS_OK; - } - - // print out stuff here incase the event got dropped on the floor above -#ifdef NS_DEBUG - if (CAPS_LOCK_IS_ON) - { - debug_DumpPaintEvent(stdout, - this, - &event, - debug_GetName(GTK_OBJECT(mSuperWin)), - (PRInt32) debug_GetRenderXID(GTK_OBJECT(mSuperWin))); - } -#endif // NS_DEBUG - - event.renderingContext = GetRenderingContext(); - if (event.renderingContext) - { - PRBool rv; - - event.renderingContext->SetClipRegion(NS_STATIC_CAST(const nsIRegion &, *mUpdateArea), - nsClipCombine_kReplace, rv); - - result = DispatchWindowEvent(&event); - NS_RELEASE(event.renderingContext); - // NS_RELEASE(mUpdateArea); - } - - - mUpdateArea->Subtract(event.rect->x, event.rect->y, event.rect->width, event.rect->height); - -#ifdef NS_DEBUG - if (WANT_PAINT_FLASHING) - { - GdkWindow *gw = GetRenderWindow(GTK_OBJECT(mSuperWin)); - if (gw) - { - GdkRectangle ar; - GdkRectangle * area = (GdkRectangle*) NULL; - - if (event.rect) - { - ar.x = event.rect->x; - ar.y = event.rect->y; - - ar.width = event.rect->width; - ar.height = event.rect->height; - - area = &ar; - } - - nsGtkUtils::gdk_window_flash(gw,1,100000,area); - } - } -#endif // NS_DEBUG } + return result; } @@ -2428,10 +2468,6 @@ gint handle_toplevel_focus_out(GtkWidget * aWidget, void nsWindow::HandleXlibExposeEvent(XEvent *event) { - nsPaintEvent pevent; - - pevent.rect = new nsRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); #if 0 if (event->xexpose.count != 0) { @@ -2448,19 +2484,25 @@ nsWindow::HandleXlibExposeEvent(XEvent *event) } while (extra_event.xexpose.count > 0); } #endif - - pevent.message = NS_PAINT; - pevent.widget = this; - pevent.eventStructType = NS_PAINT_EVENT; - pevent.point.x = event->xexpose.x; - pevent.point.y = event->xexpose.y; - /* XXX fix this */ - pevent.time = 0; - AddRef(); - OnExpose(pevent); - Release(); - delete pevent.rect; + NS_ADDREF_THIS(); + + // call the event callback + if (mEventCallback) + { + // expose.. we didn't get an Invalidate, so we should up the count here + mUpdateArea->Union(event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + + // printf("%p nsWindow::HandleXlibExposeEvent: mExposeTimer = %p\n", this, mExposeTimer); + if (!mExposeTimer) { + if (NS_NewTimer(&mExposeTimer) == NS_OK) + mExposeTimer->Init(this, 15); + } + } + + + NS_RELEASE_THIS(); } void @@ -2470,48 +2512,43 @@ nsWindow::HandleXlibButtonEvent(XButtonEvent * aButtonEvent) PRUint32 eventType = 0; - if (aButtonEvent->type == ButtonPress) - { - switch(aButtonEvent->button) - { - case 1: - eventType = NS_MOUSE_LEFT_BUTTON_DOWN; - break; + if (aButtonEvent->type == ButtonPress) { + switch(aButtonEvent->button) { + case 1: + eventType = NS_MOUSE_LEFT_BUTTON_DOWN; + break; - 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; - } + 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; } - else if (aButtonEvent->type == ButtonRelease) - { - switch(aButtonEvent->button) - { - case 1: - eventType = NS_MOUSE_LEFT_BUTTON_UP; - break; - - case 2: - eventType = NS_MOUSE_MIDDLE_BUTTON_UP; - break; - - case 3: - eventType = NS_MOUSE_RIGHT_BUTTON_UP; - break; - - default: - eventType = NS_MOUSE_LEFT_BUTTON_UP; - break; - } + } else if (aButtonEvent->type == ButtonRelease) { + switch(aButtonEvent->button) { + case 1: + eventType = NS_MOUSE_LEFT_BUTTON_UP; + break; + + case 2: + eventType = NS_MOUSE_MIDDLE_BUTTON_UP; + break; + + case 3: + eventType = NS_MOUSE_RIGHT_BUTTON_UP; + break; + + default: + eventType = NS_MOUSE_LEFT_BUTTON_UP; + break; } + } event.message = eventType; event.widget = this; diff --git a/widget/src/gtk/nsWindow.h b/widget/src/gtk/nsWindow.h index cc08fbe095b..ba18a09d61d 100644 --- a/widget/src/gtk/nsWindow.h +++ b/widget/src/gtk/nsWindow.h @@ -40,15 +40,21 @@ class nsIAppShell; * Native GTK++ window wrapper. */ -class nsWindow : public nsWidget +class nsWindow : public nsWidget, + public nsITimerCallback { public: - // nsIWidget interface + // nsIWidget interface nsWindow(); virtual ~nsWindow(); + NS_DECL_ISUPPORTS_INHERITED + + // nsITimerCallback + virtual void Notify(nsITimer* aTimer); + NS_IMETHOD WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect); NS_IMETHOD PreCreateWidget(nsWidgetInitData *aWidgetInitData); @@ -71,7 +77,6 @@ public: NS_IMETHOD BeginResizingChildren(void); NS_IMETHOD EndResizingChildren(void); - NS_IMETHOD GetAbsoluteBounds(nsRect &aRect); NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent); @@ -242,6 +247,8 @@ protected: #endif private: + nsresult SetMiniIcon(GdkPixmap *window_pixmap, + GdkBitmap *window_mask); nsresult SetIcon(GdkPixmap *window_pixmap, GdkBitmap *window_mask); nsresult SetIcon(); @@ -251,6 +258,8 @@ private: PRBool mBlockFocusEvents; PRInt32 mScrollExposeCounter; void DestroyNativeChildren(void); + + nsITimer *mExposeTimer; }; //