looping fixes. resizing still not 100% but we're getting there.

This commit is contained in:
blizzard%redhat.com 1999-02-07 03:03:07 +00:00
Родитель 1836a036a4
Коммит c9cabd839f
5 изменённых файлов: 171 добавлений и 71 удалений

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

@ -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);