зеркало из https://github.com/mozilla/gecko-dev.git
looping fixes. resizing still not 100% but we're getting there.
This commit is contained in:
Родитель
1836a036a4
Коммит
c9cabd839f
|
@ -37,6 +37,14 @@
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
static NS_DEFINE_IID(kCWindow, NS_WINDOW_CID);
|
||||
static NS_DEFINE_IID(kCChild, NS_CHILD_CID);
|
||||
|
||||
struct EventInfo {
|
||||
nsWidget *widget; // the widget
|
||||
nsRect *rect; // the rect
|
||||
};
|
||||
|
||||
struct nsKeyConverter {
|
||||
int vkCode; // Platform independent key code
|
||||
int keysym; // GDK keysym key code
|
||||
|
@ -328,10 +336,29 @@ void InitFocusEvent(GdkEventFocus *aGEF,
|
|||
=============================================================
|
||||
==============================================================*/
|
||||
|
||||
// this function will clear the queue of any resize
|
||||
// or move events
|
||||
static gint
|
||||
idle_resize_cb(gpointer data)
|
||||
{
|
||||
EventInfo *info = (EventInfo *)data;
|
||||
// g_print("idle_resize_cb: sending event for %p\n",
|
||||
// info->widget);
|
||||
info->widget->OnResize(*info->rect);
|
||||
NS_RELEASE(info->widget);
|
||||
g_free(info);
|
||||
// this will return 0 if the list is
|
||||
// empty. that will remove this idle timeout.
|
||||
// if it's > 1 then it will be restarted and
|
||||
// this will be run again.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p)
|
||||
{
|
||||
nsWidget *widget = (nsWidget *)p;
|
||||
nsRect rect;
|
||||
nsWindow *widget = (nsWindow *)p;
|
||||
EventInfo *eventinfo = NULL;
|
||||
PRBool is_window = PR_FALSE;
|
||||
#if 0
|
||||
g_print("size_allocate: %s (%p), {x=%i, y=%i, w=%i, h=%i}\n",
|
||||
gtk_widget_get_name(w),
|
||||
|
@ -340,44 +367,60 @@ void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p)
|
|||
alloc->y,
|
||||
alloc->width,
|
||||
alloc->height);
|
||||
g_print("size_allocate: old size: {x=%i, y=%i, w=%i, h=%i}\n",
|
||||
widget->mOldSize.x,
|
||||
widget->mOldSize.y,
|
||||
widget->mOldSize.width,
|
||||
widget->mOldSize.height);
|
||||
g_print("size_allocate: requested size: {x=%i, y=%i, w=%i, h=%i}\n",
|
||||
widget->mRequestedSize.x,
|
||||
widget->mRequestedSize.y,
|
||||
widget->mRequestedSize.width,
|
||||
widget->mRequestedSize.height);
|
||||
#endif
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = alloc->width;
|
||||
rect.height = alloc->height;
|
||||
// always send toplevel resize events and don't lock it.
|
||||
if (widget->mIsToplevel) {
|
||||
printf("handle_size_allocate: top level resize\n");
|
||||
widget->mResizeEventsPending = 0;
|
||||
widget->OnResizing = PR_TRUE;
|
||||
widget->OnResize(rect);
|
||||
widget->OnResizing = PR_FALSE;
|
||||
// only send the event if someone requested this...
|
||||
if (widget->mRequestedSize.x != 0 &&
|
||||
widget->mRequestedSize.y != 0 &&
|
||||
widget->mRequestedSize.width != 0 &&
|
||||
widget->mRequestedSize.height != 0 ) {
|
||||
// g_print("size_allocate: sending event because it was requested....\n");
|
||||
eventinfo = (EventInfo *)g_malloc(sizeof(struct EventInfo));
|
||||
eventinfo->rect = new nsRect();
|
||||
eventinfo->rect->x = 0;
|
||||
eventinfo->rect->y = 0;
|
||||
// lying!
|
||||
eventinfo->rect->width = widget->mRequestedSize.width;
|
||||
eventinfo->rect->height = widget->mRequestedSize.height;
|
||||
eventinfo->widget = widget;
|
||||
// don't go destroying my widget until I'm done with it, dammit.
|
||||
NS_ADDREF(widget);
|
||||
gtk_idle_add(idle_resize_cb, eventinfo);
|
||||
widget->mOldSize.x = alloc->x;
|
||||
widget->mOldSize.y = alloc->y;
|
||||
widget->mOldSize.width = alloc->width;
|
||||
widget->mOldSize.height = alloc->height;
|
||||
}
|
||||
else if (widget->mResizeEventsPending) {
|
||||
// printf("%d resize events pending.\n", widget->mResizeEventsPending);
|
||||
// reset the counter
|
||||
widget->mResizeEventsPending = 0;
|
||||
// only send the event it we are not already doing a move
|
||||
if (widget->OnResizing == PR_FALSE) {
|
||||
widget->OnResizing = PR_TRUE;
|
||||
widget->OnResize(rect);
|
||||
widget->OnResizing = PR_FALSE;
|
||||
} else {
|
||||
printf("handle_size_allocate: skipping notification of resize event - OnResize already in progress.\n");
|
||||
}
|
||||
}
|
||||
if (widget->mMoveEventsPending) {
|
||||
// reset the counter
|
||||
widget->mMoveEventsPending = 0;
|
||||
// careful not to reenter the resizing
|
||||
if (widget->OnMoving == PR_FALSE) {
|
||||
widget->OnMoving = PR_TRUE;
|
||||
widget->OnMove(alloc->x, alloc->y);
|
||||
widget->OnMoving = PR_FALSE;
|
||||
} else {
|
||||
printf("handle_size_allocate: skipping notification of move event - OnMove already in progress.\n");
|
||||
}
|
||||
else if (widget->mIsToplevel &&
|
||||
(widget->mOldSize.width != alloc->width ||
|
||||
widget->mOldSize.height != alloc->height)) {
|
||||
//g_print("size_allocate: sending event for toplevel....\n");
|
||||
eventinfo = (EventInfo *)g_malloc(sizeof(struct EventInfo));
|
||||
eventinfo->rect = new nsRect();
|
||||
eventinfo->rect->x = 0;
|
||||
eventinfo->rect->y = 0;
|
||||
// lying!
|
||||
eventinfo->rect->width = alloc->width;
|
||||
eventinfo->rect->height = alloc->height;
|
||||
eventinfo->widget = widget;
|
||||
// don't go destroying my widget until I'm done with it, dammit.
|
||||
NS_ADDREF(widget);
|
||||
gtk_idle_add(idle_resize_cb, eventinfo);
|
||||
widget->mOldSize.x = alloc->x;
|
||||
widget->mOldSize.y = alloc->y;
|
||||
widget->mOldSize.width = alloc->width;
|
||||
widget->mOldSize.height = alloc->height;
|
||||
}
|
||||
memset(&widget->mRequestedSize, 0, sizeof(nsRect));
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
|
||||
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
||||
PRBool nsWidget::OnResizing = PR_FALSE;
|
||||
PRBool nsWidget::OnMoving = PR_FALSE;
|
||||
|
||||
//#define DBG 1
|
||||
|
||||
nsWidget::nsWidget()
|
||||
|
@ -59,9 +56,15 @@ nsWidget::nsWidget()
|
|||
mBounds.height = 0;
|
||||
mIsDestroying = PR_FALSE;
|
||||
mOnDestroyCalled = PR_FALSE;
|
||||
mMoveEventsPending = 0;
|
||||
mResizeEventsPending = 0;
|
||||
mIsToplevel = PR_FALSE;
|
||||
mRequestedSize.x = 0;
|
||||
mRequestedSize.y = 0;
|
||||
mRequestedSize.width = 0;
|
||||
mRequestedSize.height = 0;
|
||||
mOldSize.x = 0;
|
||||
mOldSize.y = 0;
|
||||
mOldSize.width = 0;
|
||||
mOldSize.height = 0;
|
||||
}
|
||||
|
||||
nsWidget::~nsWidget()
|
||||
|
@ -178,7 +181,6 @@ NS_METHOD nsWidget::Move(PRUint32 aX, PRUint32 aY)
|
|||
{
|
||||
mBounds.x = aX;
|
||||
mBounds.y = aY;
|
||||
mMoveEventsPending++;
|
||||
::gtk_layout_move(GTK_LAYOUT(mWidget->parent), mWidget, aX, aY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -186,20 +188,21 @@ NS_METHOD nsWidget::Move(PRUint32 aX, PRUint32 aY)
|
|||
NS_METHOD nsWidget::Resize(PRUint32 aWidth, PRUint32 aHeight, PRBool aRepaint)
|
||||
{
|
||||
#if 0
|
||||
printf("nsWidget::Resize %s (%p) to %d %d %d events pending %s\n",
|
||||
printf("nsWidget::Resize %s (%p) to %d %d\n",
|
||||
gtk_widget_get_name(mWidget), this,
|
||||
aWidth, aHeight, mResizeEventsPending,
|
||||
( nsWidget::OnResizing ? "OnResize in progress" : "" ));
|
||||
aWidth, aHeight);
|
||||
#endif
|
||||
if (nsWidget::OnResizing && mBounds.width == aWidth && mBounds.height == aHeight) {
|
||||
// printf("Skipping resize because we're in an OnResize and we just got set to the same size.\n");
|
||||
}
|
||||
else {
|
||||
mBounds.width = aWidth;
|
||||
mBounds.height = aHeight;
|
||||
mResizeEventsPending++;
|
||||
::gtk_widget_set_usize(mWidget, aWidth, aHeight);
|
||||
}
|
||||
mOldSize.x = mBounds.x;
|
||||
mOldSize.y = mBounds.y;
|
||||
mOldSize.width = aWidth;
|
||||
mOldSize.height = aWidth;
|
||||
mRequestedSize.x = mBounds.x;
|
||||
mRequestedSize.y = mBounds.y;
|
||||
mRequestedSize.width = aWidth;
|
||||
mRequestedSize.height = aHeight;
|
||||
mBounds.width = aWidth;
|
||||
mBounds.height = aHeight;
|
||||
::gtk_widget_set_usize(mWidget, aWidth, aHeight);
|
||||
|
||||
if (aRepaint)
|
||||
if (GTK_WIDGET_VISIBLE (mWidget))
|
||||
|
@ -536,6 +539,19 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
|
|||
nsNativeWidget aNativeParent)
|
||||
{
|
||||
GtkWidget *parentWidget = nsnull;
|
||||
nsWidget *blah = NULL;
|
||||
|
||||
#if 0
|
||||
if (aParent)
|
||||
g_print("nsWidget::CreateWidget (%p) nsIWidget parent\n",
|
||||
this);
|
||||
else if (aNativeParent)
|
||||
g_print("nsWidget::CreateWidget (%p) native parent\n",
|
||||
this);
|
||||
else if(aAppShell)
|
||||
g_print("nsWidget::CreateWidget (%p) nsAppShell parent\n",
|
||||
this);
|
||||
#endif
|
||||
|
||||
gtk_widget_push_colormap(gdk_rgb_get_cmap());
|
||||
gtk_widget_push_visual(gdk_rgb_get_visual());
|
||||
|
@ -554,6 +570,9 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
|
|||
}
|
||||
|
||||
mBounds = aRect;
|
||||
// if we came from a native parent, make sure to catch the resize events.
|
||||
if (aNativeParent == NULL)
|
||||
mIsToplevel = PR_TRUE;
|
||||
CreateNative (parentWidget);
|
||||
|
||||
Resize(aRect.width, aRect.height, PR_FALSE);
|
||||
|
@ -561,12 +580,15 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
|
|||
if (parentWidget)
|
||||
gtk_layout_put(GTK_LAYOUT(parentWidget), mWidget, aRect.x, aRect.y);
|
||||
|
||||
// this is handled now in the nsWindow class
|
||||
#if 0
|
||||
// connect the size allocate to the
|
||||
gtk_signal_connect(GTK_OBJECT(mWidget),
|
||||
"size_allocate",
|
||||
GTK_SIGNAL_FUNC(handle_size_allocate),
|
||||
this);
|
||||
|
||||
if (mIsToplevel)
|
||||
gtk_signal_connect(GTK_OBJECT(mWidget),
|
||||
"size_allocate",
|
||||
GTK_SIGNAL_FUNC(handle_size_allocate),
|
||||
this);
|
||||
#endif
|
||||
gtk_widget_pop_colormap();
|
||||
gtk_widget_pop_visual();
|
||||
|
||||
|
|
|
@ -113,14 +113,10 @@ class nsWidget : public nsBaseWidget
|
|||
PRBool ConvertStatus(nsEventStatus aStatus);
|
||||
PRBool DispatchMouseEvent(nsMouseEvent& aEvent);
|
||||
PRBool DispatchStandardEvent(PRUint32 aMsg);
|
||||
// keep track of the events pending...
|
||||
PRUint32 mMoveEventsPending;
|
||||
PRUint32 mResizeEventsPending;
|
||||
// are we a "top level" widget?
|
||||
PRBool mIsToplevel;
|
||||
// are we doing a OnResize or OnMove? Be careful not to recurse.
|
||||
static PRBool OnResizing;
|
||||
static PRBool OnMoving;
|
||||
nsRect mRequestedSize;
|
||||
nsRect mOldSize;
|
||||
protected:
|
||||
virtual void InitCallbacks(char * aName = nsnull);
|
||||
virtual void OnDestroy();
|
||||
|
|
|
@ -38,7 +38,34 @@
|
|||
|
||||
//#define DBG 0
|
||||
|
||||
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
|
||||
// for nsISupports
|
||||
NS_IMPL_ADDREF(nsWindow)
|
||||
NS_IMPL_RELEASE(nsWindow)
|
||||
|
||||
/**
|
||||
* Implement the standard QueryInterface for NS_IWIDGET_IID and NS_ISUPPORTS_IID
|
||||
* @modify gpk 8/4/98
|
||||
* @param aIID The name of the class implementing the method
|
||||
* @param _classiiddef The name of the #define symbol that defines the IID
|
||||
* for the class (e.g. NS_ISUPPORTS_IID)
|
||||
*
|
||||
*/
|
||||
nsresult nsWindow::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kCWindow, NS_WINDOW_CID);
|
||||
if (aIID.Equals(kCWindow)) {
|
||||
*aInstancePtr = (void*) ((nsWindow*)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return nsWidget::QueryInterface(aIID,aInstancePtr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -151,6 +178,7 @@ NS_METHOD nsWindow::PreCreateWidget(nsWidgetInitData *aInitData)
|
|||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsWindow::CreateNative(GtkWidget *parentWidget)
|
||||
{
|
||||
gchar *name = NULL;
|
||||
mWidget = gtk_layout_new(PR_FALSE, PR_FALSE);
|
||||
GTK_WIDGET_SET_FLAGS(mWidget, GTK_CAN_FOCUS);
|
||||
gtk_widget_set_app_paintable(mWidget, PR_TRUE);
|
||||
|
@ -180,7 +208,8 @@ NS_METHOD nsWindow::CreateNative(GtkWidget *parentWidget)
|
|||
gtk_widget_show (mVBox);
|
||||
gtk_container_add(GTK_CONTAINER(mShell), mVBox);
|
||||
gtk_box_pack_start(GTK_BOX(mVBox), mWidget, PR_TRUE, PR_TRUE, 0);
|
||||
mIsToplevel = PR_TRUE;
|
||||
// this is done in CreateWidget now...
|
||||
//mIsToplevel = PR_TRUE;
|
||||
gtk_signal_connect(GTK_OBJECT(mShell),
|
||||
"delete_event",
|
||||
GTK_SIGNAL_FUNC(handle_delete_event),
|
||||
|
@ -189,7 +218,13 @@ NS_METHOD nsWindow::CreateNative(GtkWidget *parentWidget)
|
|||
}
|
||||
|
||||
// Force cursor to default setting
|
||||
gtk_widget_set_name(mWidget, "nsWindow");
|
||||
name = (char *)g_malloc(50);
|
||||
memset(name, 0, 50);
|
||||
if (mIsToplevel)
|
||||
sprintf(name, "nsWindow (%p) (TopLevel)", this);
|
||||
else
|
||||
sprintf(name, "nsWindow (%p)", this);
|
||||
gtk_widget_set_name(mWidget, name);
|
||||
mCursor = eCursor_select;
|
||||
SetCursor(eCursor_standard);
|
||||
return NS_OK;
|
||||
|
@ -203,12 +238,10 @@ NS_METHOD nsWindow::CreateNative(GtkWidget *parentWidget)
|
|||
//-------------------------------------------------------------------------
|
||||
void nsWindow::InitCallbacks(char * aName)
|
||||
{
|
||||
#if 0
|
||||
gtk_signal_connect_after(GTK_OBJECT(mWidget),
|
||||
"size_allocate",
|
||||
GTK_SIGNAL_FUNC(handle_size_allocate),
|
||||
this);
|
||||
#endif
|
||||
gtk_signal_connect_after(GTK_OBJECT(mWidget),
|
||||
"button_press_event",
|
||||
GTK_SIGNAL_FUNC(handle_button_press_event),
|
||||
|
|
|
@ -45,6 +45,12 @@ public:
|
|||
nsWindow();
|
||||
virtual ~nsWindow();
|
||||
|
||||
// nsIsupports
|
||||
NS_IMETHOD_(nsrefcnt) AddRef();
|
||||
NS_IMETHOD_(nsrefcnt) Release();
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
||||
|
||||
virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
|
||||
|
||||
NS_IMETHOD PreCreateWidget(nsWidgetInitData *aWidgetInitData);
|
||||
|
|
Загрузка…
Ссылка в новой задаче