Wired up gtk widget destruction to nsWidget and related classes so that we don't ever have dangling points to dead gtk objects

This commit is contained in:
kipp%netscape.com 1999-04-30 00:13:47 +00:00
Родитель 03de3e5e0d
Коммит e109da7959
19 изменённых файлов: 483 добавлений и 248 удалений

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

@ -46,6 +46,20 @@ nsCheckButton::~nsCheckButton()
{ {
} }
void
nsCheckButton::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCheckButton) {
mCheckButton = nsnull;
}
else if (aGtkWidget == mLabel) {
mLabel = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Create the native CheckButton widget // Create the native CheckButton widget
@ -81,8 +95,13 @@ void nsCheckButton::InitCallbacks(char * aName)
GDK_KEY_RELEASE_MASK | GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK); GDK_POINTER_MOTION_MASK);
}
// Add in destroy callback
gtk_signal_connect(GTK_OBJECT(mCheckButton),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
/** /**
* Implement the standard QueryInterface for NS_IWIDGET_IID and NS_ISUPPORTS_IID * Implement the standard QueryInterface for NS_IWIDGET_IID and NS_ISUPPORTS_IID
@ -114,12 +133,13 @@ nsresult nsCheckButton::QueryInterface(const nsIID& aIID, void** aInstancePtr)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsCheckButton::SetState(const PRBool aState) NS_METHOD nsCheckButton::SetState(const PRBool aState)
{ {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mCheckButton); if (mWidget) {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mCheckButton);
item->active = (gboolean) aState; item->active = (gboolean) aState;
gtk_widget_queue_draw(GTK_WIDGET(item)); gtk_widget_queue_draw(GTK_WIDGET(item));
}
return NS_OK; return NS_OK;
} }
@ -130,12 +150,14 @@ NS_METHOD nsCheckButton::SetState(const PRBool aState)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsCheckButton::GetState(PRBool& aState) NS_METHOD nsCheckButton::GetState(PRBool& aState)
{ {
aState = (PRBool) GTK_TOGGLE_BUTTON(mCheckButton)->active; aState = PR_TRUE;
if (mWidget) {
// The check button will have been toggled twice (cough) - aState = (PRBool) GTK_TOGGLE_BUTTON(mCheckButton)->active;
// once by GTK and once by gecko. This is obviously messed up.
aState = !aState;
// The check button will have been toggled twice (cough) -
// once by GTK and once by gecko. This is obviously messed up.
aState = !aState;
}
return NS_OK; return NS_OK;
} }
@ -146,16 +168,22 @@ NS_METHOD nsCheckButton::GetState(PRBool& aState)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsCheckButton::SetLabel(const nsString& aText) NS_METHOD nsCheckButton::SetLabel(const nsString& aText)
{ {
NS_ALLOC_STR_BUF(label, aText, 256); if (mWidget) {
if (mLabel) { NS_ALLOC_STR_BUF(label, aText, 256);
gtk_label_set(GTK_LABEL(mLabel), label); if (mLabel) {
} else { gtk_label_set(GTK_LABEL(mLabel), label);
mLabel = gtk_label_new(label); } else {
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5); mLabel = gtk_label_new(label);
gtk_container_add(GTK_CONTAINER(mCheckButton), mLabel); gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_widget_show(mLabel); gtk_container_add(GTK_CONTAINER(mCheckButton), mLabel);
gtk_widget_show(mLabel);
gtk_signal_connect(GTK_OBJECT(mLabel),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
NS_FREE_STR_BUF(label);
} }
NS_FREE_STR_BUF(label);
return NS_OK; return NS_OK;
} }
@ -167,11 +195,13 @@ NS_METHOD nsCheckButton::SetLabel(const nsString& aText)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsCheckButton::GetLabel(nsString& aBuffer) NS_METHOD nsCheckButton::GetLabel(nsString& aBuffer)
{ {
char * text; aBuffer.SetLength(0);
if (mLabel) { if (mWidget) {
gtk_label_get(GTK_LABEL(mLabel), &text); char * text;
aBuffer.SetLength(0); if (mLabel) {
aBuffer.Append(text); gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.Append(text);
}
} }
return NS_OK; return NS_OK;
} }

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

@ -53,6 +53,7 @@ public:
protected: protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow); NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void InitCallbacks(char * aName = nsnull); virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mLabel; GtkWidget *mLabel;
GtkWidget *mCheckButton; GtkWidget *mCheckButton;

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

@ -42,8 +42,6 @@ nsComboBox::nsComboBox() : nsWidget(), nsIListWidget(), nsIComboBox()
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mMultiSelect = PR_FALSE; mMultiSelect = PR_FALSE;
// mBackground = NS_RGB(124, 124, 124);
mItems = nsnull; mItems = nsnull;
mNumItems = 0; mNumItems = 0;
} }
@ -55,14 +53,12 @@ nsComboBox::nsComboBox() : nsWidget(), nsIListWidget(), nsIComboBox()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
nsComboBox::~nsComboBox() nsComboBox::~nsComboBox()
{ {
for ( GList *items = mItems; items != NULL; items = (GList *) g_list_next(items)) if (mItems) {
{ for (GList *items = mItems; items; items = (GList*) g_list_next(items)){
g_free(items->data); g_free(items->data);
} }
g_list_free(mItems); g_list_free(mItems);
#if 0 }
gtk_widget_destroy(mCombo);
#endif
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -88,8 +84,10 @@ NS_METHOD nsComboBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
{ {
NS_ALLOC_STR_BUF(val, aItem, 256); NS_ALLOC_STR_BUF(val, aItem, 256);
mItems = g_list_insert( mItems, g_strdup(val), aPosition ); mItems = g_list_insert( mItems, g_strdup(val), aPosition );
gtk_combo_set_popdown_strings( GTK_COMBO( mCombo ), mItems );
mNumItems++; mNumItems++;
if (mCombo) {
gtk_combo_set_popdown_strings( GTK_COMBO( mCombo ), mItems );
}
NS_FREE_STR_BUF(val); NS_FREE_STR_BUF(val);
return NS_OK; return NS_OK;
} }
@ -138,8 +136,10 @@ PRBool nsComboBox::RemoveItemAt(PRInt32 aPosition)
g_free(g_list_nth(mItems, aPosition)->data); g_free(g_list_nth(mItems, aPosition)->data);
mItems = g_list_remove_link(mItems, g_list_nth(mItems, aPosition)); mItems = g_list_remove_link(mItems, g_list_nth(mItems, aPosition));
gtk_combo_set_popdown_strings(GTK_COMBO( mCombo ), mItems);
mNumItems--; mNumItems--;
if (mCombo) {
gtk_combo_set_popdown_strings(GTK_COMBO( mCombo ), mItems);
}
return PR_TRUE; return PR_TRUE;
} }
else else
@ -153,13 +153,11 @@ PRBool nsComboBox::RemoveItemAt(PRInt32 aPosition)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRBool nsComboBox::GetItemAt(nsString& anItem, PRInt32 aPosition) PRBool nsComboBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
{ {
PRBool result = PR_FALSE;
if (aPosition >= 0 && aPosition < mNumItems) { if (aPosition >= 0 && aPosition < mNumItems) {
anItem = (gchar *) g_list_nth(mItems, aPosition)->data; anItem = (gchar *) g_list_nth(mItems, aPosition)->data;
return PR_TRUE; return PR_TRUE;
} }
else return PR_FALSE;
return PR_FALSE;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -169,7 +167,10 @@ PRBool nsComboBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsComboBox::GetSelectedItem(nsString& aItem) NS_METHOD nsComboBox::GetSelectedItem(nsString& aItem)
{ {
aItem = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(mCombo)->entry)); aItem.Truncate();
if (mCombo) {
aItem = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(mCombo)->entry));
}
return NS_OK; return NS_OK;
} }
@ -200,7 +201,10 @@ NS_METHOD nsComboBox::SelectItem(PRInt32 aPosition)
if (!pos) if (!pos)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(mCombo)->entry), (gchar *) pos->data); if (mCombo) {
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(mCombo)->entry),
(gchar *) pos->data);
}
return NS_OK; return NS_OK;
} }
@ -288,11 +292,25 @@ NS_METHOD nsComboBox::CreateNative(GtkWidget *parentWindow)
/* make the stuff uneditable */ /* make the stuff uneditable */
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(mCombo)->entry), PR_FALSE); gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(mCombo)->entry), PR_FALSE);
gtk_container_add(GTK_CONTAINER(mWidget), mCombo); gtk_container_add(GTK_CONTAINER(mWidget), mCombo);
// gtk_combo_set_value_in_list(GTK_COMBO(mCombo), PR_TRUE, PR_TRUE); gtk_signal_connect(GTK_OBJECT(mCombo),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
return NS_OK; return NS_OK;
} }
void
nsComboBox::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCombo) {
mCombo = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// move, paint, resizes message - ignore // move, paint, resizes message - ignore

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* *
* The contents of this file are subject to the Netscape Public License * The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in * Version 1.0 (the "NPL"); you may not use this file except in
@ -61,10 +61,9 @@ public:
protected: protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow); NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mCombo; /* workaround for gtkcombo bug */ GtkWidget *mCombo; /* workaround for gtkcombo bug */
GtkWidget *mPullDownMenu;
GtkWidget *mOptionMenu;
GList *mItems; GList *mItems;
PRBool mMultiSelect; PRBool mMultiSelect;
int mNumItems; int mNumItems;

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

@ -65,23 +65,27 @@ static void file_cancel_clicked(GtkWidget *w, PRBool *ret)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRBool nsFileWidget::Show() PRBool nsFileWidget::Show()
{ {
// make things shorter
GtkFileSelection *fs = GTK_FILE_SELECTION(mWidget);
PRBool ret; PRBool ret;
if (mWidget) {
// make things shorter
GtkFileSelection *fs = GTK_FILE_SELECTION(mWidget);
gtk_window_set_modal(GTK_WINDOW(mWidget), PR_TRUE); gtk_window_set_modal(GTK_WINDOW(mWidget), PR_TRUE);
gtk_widget_show(mWidget); gtk_widget_show(mWidget);
// handle close, destroy, etc on the dialog
gtk_signal_connect(GTK_OBJECT(fs->ok_button), "clicked",
GTK_SIGNAL_FUNC(file_ok_clicked),
&ret);
gtk_signal_connect(GTK_OBJECT(fs->cancel_button), "clicked",
GTK_SIGNAL_FUNC(file_cancel_clicked),
&ret);
// start new loop. ret is set in the above callbacks.
gtk_main();
// handle close, destroy, etc on the dialog
gtk_signal_connect(GTK_OBJECT(fs->ok_button), "clicked",
GTK_SIGNAL_FUNC(file_ok_clicked),
&ret);
gtk_signal_connect(GTK_OBJECT(fs->cancel_button), "clicked",
GTK_SIGNAL_FUNC(file_cancel_clicked),
&ret);
// start new loop. ret is set in the above callbacks.
gtk_main();
}
else {
ret = PR_FALSE;
}
return ret; return ret;
} }
@ -109,27 +113,26 @@ NS_METHOD nsFileWidget::SetFilterList(PRUint32 aNumberOfFilters,
NS_METHOD nsFileWidget::GetFile(nsString& aFile) NS_METHOD nsFileWidget::GetFile(nsString& aFile)
{ {
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget)); aFile.Truncate();
if (mWidget) {
aFile.SetLength(0); gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
aFile.Append(fn); aFile.Append(fn);
// g_free(fn); // g_free(fn);
}
return NS_OK; return NS_OK;
} }
NS_METHOD nsFileWidget::GetFile(nsFileSpec& aFile) NS_METHOD nsFileWidget::GetFile(nsFileSpec& aFile)
{ {
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget)); if (mWidget) {
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
aFile = fn; // Put the filename into the nsFileSpec instance. aFile = fn; // Put the filename into the nsFileSpec instance.
}
return NS_OK; return NS_OK;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Get the file + path // Get the file + path
@ -137,10 +140,12 @@ NS_METHOD nsFileWidget::GetFile(nsFileSpec& aFile)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsFileWidget::SetDefaultString(nsString& aString) NS_METHOD nsFileWidget::SetDefaultString(nsString& aString)
{ {
char *fn = aString.ToNewCString(); if (mWidget) {
g_print("%s\n",fn); char *fn = aString.ToNewCString();
gtk_file_selection_set_filename(GTK_FILE_SELECTION(mWidget), fn); g_print("%s\n",fn);
delete[] fn; gtk_file_selection_set_filename(GTK_FILE_SELECTION(mWidget), fn);
delete[] fn;
}
return NS_OK; return NS_OK;
} }
@ -183,6 +188,10 @@ NS_METHOD nsFileWidget::Create(nsIWidget *aParent,
char *title = mTitle.ToNewCString(); char *title = mTitle.ToNewCString();
mWidget = gtk_file_selection_new(title); mWidget = gtk_file_selection_new(title);
gtk_signal_connect(GTK_OBJECT(mWidget),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
// Hide the file column for the folder case. // Hide the file column for the folder case.
if(aMode == eMode_getfolder) { if(aMode == eMode_getfolder) {
@ -194,6 +203,22 @@ NS_METHOD nsFileWidget::Create(nsIWidget *aParent,
return NS_OK; return NS_OK;
} }
gint
nsFileWidget::DestroySignal(GtkWidget * aGtkWidget,
nsFileWidget* aWidget)
{
aWidget->OnDestroySignal(aGtkWidget);
return TRUE;
}
void
nsFileWidget::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mWidget) {
mWidget = nsnull;
}
}
nsFileDlgResults nsFileWidget::GetFile(nsIWidget *aParent, nsFileDlgResults nsFileWidget::GetFile(nsIWidget *aParent,
nsString &promptString, nsString &promptString,
nsFileSpec &theFileSpec) nsFileSpec &theFileSpec)

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

@ -32,35 +32,35 @@
class nsFileWidget : public nsIFileWidget class nsFileWidget : public nsIFileWidget
{ {
public: public:
nsFileWidget(); nsFileWidget();
virtual ~nsFileWidget(); virtual ~nsFileWidget();
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
PRBool OnPaint(); PRBool OnPaint();
// nsIWidget interface // nsIWidget interface
NS_IMETHOD Create(nsIWidget *aParent, NS_IMETHOD Create(nsIWidget *aParent,
nsString& aTitle, nsString& aTitle,
nsFileDlgMode aMode, nsFileDlgMode aMode,
nsIDeviceContext *aContext = nsnull, nsIDeviceContext *aContext = nsnull,
nsIAppShell *aAppShell = nsnull, nsIAppShell *aAppShell = nsnull,
nsIToolkit *aToolkit = nsnull, nsIToolkit *aToolkit = nsnull,
void *aInitData = nsnull); void *aInitData = nsnull);
// nsIFileWidget part // nsIFileWidget part
virtual PRBool Show(); virtual PRBool Show();
NS_IMETHOD GetFile(nsString& aFile); NS_IMETHOD GetFile(nsString& aFile);
NS_IMETHOD GetFile(nsFileSpec& aFile); NS_IMETHOD GetFile(nsFileSpec& aFile);
NS_IMETHOD SetDefaultString(nsString& aFile); NS_IMETHOD SetDefaultString(nsString& aFile);
NS_IMETHOD SetFilterList(PRUint32 aNumberOfFilters, NS_IMETHOD SetFilterList(PRUint32 aNumberOfFilters,
const nsString aTitles[], const nsString aTitles[],
const nsString aFilters[]); const nsString aFilters[]);
NS_IMETHOD GetDisplayDirectory(nsString& aDirectory); NS_IMETHOD GetDisplayDirectory(nsString& aDirectory);
NS_IMETHOD SetDisplayDirectory(nsString& aDirectory); NS_IMETHOD SetDisplayDirectory(nsString& aDirectory);
virtual nsFileDlgResults GetFile(nsIWidget *aParent, virtual nsFileDlgResults GetFile(nsIWidget *aParent,
nsString &promptString, nsString &promptString,
@ -74,15 +74,20 @@ class nsFileWidget : public nsIFileWidget
nsString &promptString, nsString &promptString,
nsFileSpec &theFileSpec); nsFileSpec &theFileSpec);
protected: protected:
GtkWidget *mWidget; static gint DestroySignal(GtkWidget * aGtkWidget,
nsString mTitle; nsFileWidget* aWidget);
nsFileDlgMode mMode;
PRUint32 mNumberOfFilters; virtual void OnDestroySignal(GtkWidget* aGtkWidget);
const nsString* mTitles;
const nsString* mFilters; GtkWidget *mWidget;
nsString mDefault; nsString mTitle;
nsString mDisplayDirectory; nsFileDlgMode mMode;
PRUint32 mNumberOfFilters;
const nsString* mTitles;
const nsString* mFilters;
nsString mDefault;
nsString mDisplayDirectory;
}; };
#endif // nsFileWidget_h__ #endif // nsFileWidget_h__

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

@ -431,8 +431,8 @@ void menu_item_activate_handler(GtkWidget *w, gpointer p)
mevent.mMenuItem = menuItem; mevent.mMenuItem = menuItem;
mevent.time = PR_IntervalNow(); mevent.time = PR_IntervalNow();
nsEventStatus status;
// FIXME - THIS SHOULD WORK. FIX EVENTS FOR XP CODE!!!!! (pav) // FIXME - THIS SHOULD WORK. FIX EVENTS FOR XP CODE!!!!! (pav)
// nsEventStatus status;
// mevent.widget->DispatchEvent((nsGUIEvent *)&mevent, status); // mevent.widget->DispatchEvent((nsGUIEvent *)&mevent, status);
menuItem->QueryInterface(kIMenuListenerIID, (void**)&menuListener); menuItem->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
@ -458,16 +458,14 @@ void menu_map_handler(GtkWidget *w, gpointer p)
mevent.time = PR_IntervalNow(); mevent.time = PR_IntervalNow();
nsEventStatus status;
menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener); menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
if(menuListener) { if(menuListener) {
menuListener->MenuConstruct( menuListener->MenuConstruct(
mevent, mevent,
nsnull, //parent window nsnull, //parent window
nsnull, //menuNode nsnull, //menuNode
nsnull ); // webshell nsnull ); // webshell
NS_IF_RELEASE(menuListener); NS_IF_RELEASE(menuListener);
} }
} }
@ -488,8 +486,6 @@ void menu_unmap_handler(GtkWidget *w, gpointer p)
mevent.time = PR_IntervalNow(); mevent.time = PR_IntervalNow();
nsEventStatus status;
menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener); menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
if(menuListener) { if(menuListener) {
menuListener->MenuDestruct(mevent); menuListener->MenuDestruct(mevent);

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

@ -54,6 +54,7 @@ public:
protected: protected:
NS_METHOD CreateNative(GtkWidget *parentWindow); NS_METHOD CreateNative(GtkWidget *parentWindow);
GtkJustification GetNativeAlignment(); GtkJustification GetNativeAlignment();
nsLabelAlignment mAlignment; nsLabelAlignment mAlignment;
}; };

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

@ -37,7 +37,6 @@ nsListBox::nsListBox() : nsWidget(), nsIListWidget(), nsIListBox()
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mMultiSelect = PR_FALSE; mMultiSelect = PR_FALSE;
mCList = nsnull; mCList = nsnull;
// mBackground = NS_RGB(124, 124, 124);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -47,13 +46,6 @@ nsListBox::nsListBox() : nsWidget(), nsIListWidget(), nsIListBox()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
nsListBox::~nsListBox() nsListBox::~nsListBox()
{ {
#if 0
if (mCList)
{
::gtk_widget_destroy(mCList);
mCList = nsnull;
}
#endif
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -93,12 +85,12 @@ nsresult nsListBox::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_METHOD nsListBox::SetMultipleSelection(PRBool aMultipleSelections) NS_METHOD nsListBox::SetMultipleSelection(PRBool aMultipleSelections)
{ {
mMultiSelect = aMultipleSelections; mMultiSelect = aMultipleSelections;
if (mCList) {
if (mMultiSelect) if (mMultiSelect)
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_MULTIPLE); gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_MULTIPLE);
else else
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE); gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE);
}
return NS_OK; return NS_OK;
} }
@ -111,20 +103,19 @@ NS_METHOD nsListBox::SetMultipleSelection(PRBool aMultipleSelections)
NS_METHOD nsListBox::AddItemAt(nsString &aItem, PRInt32 aPosition) NS_METHOD nsListBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
{ {
// cout << "nsListBox::AddItemAt(" << aItem << "," << aPosition << ")" << endl; if (mCList) {
char *buf = aItem.ToNewCString();
gchar *text[2];
text[0] = buf;
text[1] = (char *)NULL;
gtk_clist_insert(GTK_CLIST(mCList), (int)aPosition, text);
char *buf = aItem.ToNewCString(); // XXX Im not sure using the string address is the right thing to
gchar *text[2]; // store in the row data.
text[0] = buf; gtk_clist_set_row_data(GTK_CLIST(mCList), aPosition, (gpointer)&aItem);
text[1] = (char *)NULL;
gtk_clist_insert(GTK_CLIST(mCList), (int)aPosition, text);
// XXX Im not sure using the string address is the right thing to
// store in the row data.
gtk_clist_set_row_data(GTK_CLIST(mCList), (int)aPosition, (gpointer)&aItem);
delete[] buf;
delete[] buf;
}
return NS_OK; return NS_OK;
} }
@ -135,14 +126,13 @@ NS_METHOD nsListBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRInt32 nsListBox::FindItem(nsString &aItem, PRInt32 aStartPos) PRInt32 nsListBox::FindItem(nsString &aItem, PRInt32 aStartPos)
{ {
// cout << "nsListBox::FindItem(" << aItem << "," << aStartPos << ")" << endl; int index = -1;
if (mCList) {
int index = gtk_clist_find_row_from_data(GTK_CLIST(mCList), (gpointer)&aItem); index = gtk_clist_find_row_from_data(GTK_CLIST(mCList), (gpointer)&aItem);
if (index < aStartPos) {
if (index < aStartPos) { index = -1;
index = -1; }
} }
return index; return index;
} }
@ -153,7 +143,12 @@ PRInt32 nsListBox::FindItem(nsString &aItem, PRInt32 aStartPos)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRInt32 nsListBox::GetItemCount() PRInt32 nsListBox::GetItemCount()
{ {
return GTK_CLIST(mCList)->rows; if (mCList) {
return GTK_CLIST(mCList)->rows;
}
else {
return 0;
}
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -163,7 +158,9 @@ PRInt32 nsListBox::GetItemCount()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRBool nsListBox::RemoveItemAt(PRInt32 aPosition) PRBool nsListBox::RemoveItemAt(PRInt32 aPosition)
{ {
gtk_clist_remove(GTK_CLIST(mCList), aPosition); if (mCList) {
gtk_clist_remove(GTK_CLIST(mCList), aPosition);
}
return PR_TRUE; return PR_TRUE;
} }
@ -175,13 +172,14 @@ PRBool nsListBox::RemoveItemAt(PRInt32 aPosition)
PRBool nsListBox::GetItemAt(nsString& anItem, PRInt32 aPosition) PRBool nsListBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
{ {
PRBool result = PR_FALSE; PRBool result = PR_FALSE;
char *text = nsnull; anItem.Truncate();
if (mCList) {
gtk_clist_get_text(GTK_CLIST(mCList),aPosition,0,&text); char *text = nsnull;
if (text) { gtk_clist_get_text(GTK_CLIST(mCList),aPosition,0,&text);
anItem.SetLength(0); if (text) {
anItem.Append(text); anItem.Append(text);
result = PR_TRUE; result = PR_TRUE;
}
} }
return result; return result;
} }
@ -193,19 +191,21 @@ PRBool nsListBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsListBox::GetSelectedItem(nsString& aItem) NS_METHOD nsListBox::GetSelectedItem(nsString& aItem)
{ {
PRInt32 i=0, index=-1; aItem.Truncate();
GtkCList *clist = GTK_CLIST(mCList); if (mCList) {
GList *list = clist->row_list; PRInt32 i=0, index=-1;
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && index == -1; i++, list = list->next) { for (i=0; i < clist->rows && index == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) { if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
char *text = nsnull; char *text = nsnull;
gtk_clist_get_text(GTK_CLIST(mCList),i,0,&text); gtk_clist_get_text(GTK_CLIST(mCList),i,0,&text);
if (text) { if (text) {
aItem.SetLength(0); aItem.Append(text);
aItem.Append(text); }
return NS_OK;
} }
return NS_OK;
} }
} }
return NS_OK; return NS_OK;
@ -219,19 +219,20 @@ NS_METHOD nsListBox::GetSelectedItem(nsString& aItem)
PRInt32 nsListBox::GetSelectedIndex() PRInt32 nsListBox::GetSelectedIndex()
{ {
PRInt32 i=0, index=-1; PRInt32 i=0, index=-1;
if (!mMultiSelect) { if (mCList) {
GtkCList *clist = GTK_CLIST(mCList); if (!mMultiSelect) {
GList *list = clist->row_list; GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && index == -1; i++, list = list->next) { for (i=0; i < clist->rows && index == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) { if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
index = i; index = i;
}
} }
} else {
NS_ASSERTION(PR_FALSE, "Multi selection list box does not support GetSelectedIndex()");
} }
} else {
NS_ASSERTION(PR_FALSE, "Multi selection list box does not support GetSelectedIndex()");
} }
return index; return index;
} }
@ -242,7 +243,9 @@ PRInt32 nsListBox::GetSelectedIndex()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsListBox::SelectItem(PRInt32 aPosition) NS_METHOD nsListBox::SelectItem(PRInt32 aPosition)
{ {
gtk_clist_select_row(GTK_CLIST(mCList), aPosition, 0); if (mCList) {
gtk_clist_select_row(GTK_CLIST(mCList), aPosition, 0);
}
return NS_OK; return NS_OK;
} }
@ -253,10 +256,15 @@ NS_METHOD nsListBox::SelectItem(PRInt32 aPosition)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRInt32 nsListBox::GetSelectedCount() PRInt32 nsListBox::GetSelectedCount()
{ {
if (!GTK_CLIST(mCList)->selection) if (mCList) {
if (!GTK_CLIST(mCList)->selection)
return 0;
else
return (PRInt32)g_list_length(GTK_CLIST(mCList)->selection);
}
else {
return 0; return 0;
else }
return (PRInt32)g_list_length(GTK_CLIST(mCList)->selection);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -266,16 +274,22 @@ PRInt32 nsListBox::GetSelectedCount()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsListBox::GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize) NS_METHOD nsListBox::GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
{ {
PRInt32 i=0, num = 0; if (mCList) {
GtkCList *clist = GTK_CLIST(mCList); PRInt32 i=0, num = 0;
GList *list = clist->row_list; GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && num < aSize; i++, list = list->next) { for (i=0; i < clist->rows && num < aSize; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) { if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
aIndices[num] = i; aIndices[num] = i;
num++; num++;
}
} }
} }
else {
PRInt32 i = 0;
for (i = 0; i < aSize; i++) aIndices[i] = 0;
}
return NS_OK; return NS_OK;
} }
@ -286,10 +300,12 @@ NS_METHOD nsListBox::GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsListBox::SetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize) NS_METHOD nsListBox::SetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
{ {
gtk_clist_unselect_all(GTK_CLIST(mCList)); if (mCList) {
int i; gtk_clist_unselect_all(GTK_CLIST(mCList));
for (i=0;i<aSize;i++) { int i;
SelectItem(aIndices[i]); for (i=0;i<aSize;i++) {
SelectItem(aIndices[i]);
}
} }
return NS_OK; return NS_OK;
} }
@ -301,7 +317,9 @@ NS_METHOD nsListBox::SetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsListBox::Deselect() NS_METHOD nsListBox::Deselect()
{ {
gtk_clist_unselect_all(GTK_CLIST(mCList)); if (mCList) {
gtk_clist_unselect_all(GTK_CLIST(mCList));
}
return NS_OK; return NS_OK;
} }
@ -331,7 +349,7 @@ NS_METHOD nsListBox::CreateNative(GtkWidget *parentWindow)
gtk_widget_set_name(mWidget, "nsListBox"); gtk_widget_set_name(mWidget, "nsListBox");
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (mWidget), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (mWidget),
GTK_POLICY_NEVER, GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
mCList = ::gtk_clist_new(1); mCList = ::gtk_clist_new(1);
gtk_clist_column_titles_hide(GTK_CLIST(mCList)); gtk_clist_column_titles_hide(GTK_CLIST(mCList));
@ -339,12 +357,27 @@ NS_METHOD nsListBox::CreateNative(GtkWidget *parentWindow)
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE); gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE);
SetMultipleSelection(mMultiSelect); SetMultipleSelection(mMultiSelect);
gtk_widget_show(mCList); gtk_widget_show(mCList);
gtk_signal_connect(GTK_OBJECT(mCList),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
gtk_container_add (GTK_CONTAINER (mWidget), mCList); gtk_container_add (GTK_CONTAINER (mWidget), mCList);
return NS_OK; return NS_OK;
} }
void
nsListBox::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCList) {
mCList = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// move, paint, resizes message - ignore // move, paint, resizes message - ignore

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

@ -63,6 +63,7 @@ public:
protected: protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow); NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mCList; GtkWidget *mCList;
PRBool mMultiSelect; PRBool mMultiSelect;

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

@ -228,7 +228,7 @@ NS_METHOD nsMenu::AddMenuItem(nsIMenuItem * aMenuItem)
NS_METHOD nsMenu::AddMenu(nsIMenu * aMenu) NS_METHOD nsMenu::AddMenu(nsIMenu * aMenu)
{ {
nsString Label; nsString Label;
GtkWidget *item=nsnull, *newmenu=nsnull; GtkWidget *newmenu=nsnull;
char *labelStr; char *labelStr;
void *voidData=NULL; void *voidData=NULL;

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

@ -92,9 +92,28 @@ NS_METHOD nsRadioButton::CreateNative(GtkWidget *parentWindow)
gtk_radio_button_set_group(GTK_RADIO_BUTTON(mRadioButton), nsnull); gtk_radio_button_set_group(GTK_RADIO_BUTTON(mRadioButton), nsnull);
gtk_signal_connect(GTK_OBJECT(mRadioButton),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
return NS_OK; return NS_OK;
} }
void
nsRadioButton::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mLabel) {
mLabel = nsnull;
}
else if (aGtkWidget == mRadioButton) {
mRadioButton = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
void nsRadioButton::InitCallbacks(char * aName) void nsRadioButton::InitCallbacks(char * aName)
{ {
InstallButtonPressSignal(mRadioButton); InstallButtonPressSignal(mRadioButton);
@ -120,12 +139,11 @@ void nsRadioButton::InitCallbacks(char * aName)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsRadioButton::SetState(const PRBool aState) NS_METHOD nsRadioButton::SetState(const PRBool aState)
{ {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mRadioButton); if (mWidget) {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mRadioButton);
item->active = (gboolean) aState; item->active = (gboolean) aState;
gtk_widget_queue_draw(GTK_WIDGET(item));
gtk_widget_queue_draw(GTK_WIDGET(item)); }
return NS_OK; return NS_OK;
} }
@ -135,8 +153,12 @@ NS_METHOD nsRadioButton::SetState(const PRBool aState)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsRadioButton::GetState(PRBool& aState) NS_METHOD nsRadioButton::GetState(PRBool& aState)
{ {
aState = (PRBool) GTK_TOGGLE_BUTTON(mRadioButton)->active; if (mWidget) {
aState = (PRBool) GTK_TOGGLE_BUTTON(mRadioButton)->active;
}
else {
aState = PR_TRUE;
}
return NS_OK; return NS_OK;
} }
@ -147,17 +169,23 @@ NS_METHOD nsRadioButton::GetState(PRBool& aState)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsRadioButton::SetLabel(const nsString& aText) NS_METHOD nsRadioButton::SetLabel(const nsString& aText)
{ {
NS_ALLOC_STR_BUF(label, aText, 256); if (mWidget) {
g_print("nsRadioButton::SetLabel(%s)\n",label); NS_ALLOC_STR_BUF(label, aText, 256);
if (mLabel) { g_print("nsRadioButton::SetLabel(%s)\n",label);
gtk_label_set(GTK_LABEL(mLabel), label); if (mLabel) {
} else { gtk_label_set(GTK_LABEL(mLabel), label);
mLabel = gtk_label_new(label); } else {
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5); mLabel = gtk_label_new(label);
gtk_container_add(GTK_CONTAINER(mRadioButton), mLabel); gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_widget_show(mLabel); /* XXX */ gtk_container_add(GTK_CONTAINER(mRadioButton), mLabel);
gtk_widget_show(mLabel); /* XXX */
gtk_signal_connect(GTK_OBJECT(mLabel),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
NS_FREE_STR_BUF(label);
} }
NS_FREE_STR_BUF(label);
return NS_OK; return NS_OK;
} }
@ -169,11 +197,13 @@ NS_METHOD nsRadioButton::SetLabel(const nsString& aText)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsRadioButton::GetLabel(nsString& aBuffer) NS_METHOD nsRadioButton::GetLabel(nsString& aBuffer)
{ {
char * text; aBuffer.Truncate();
if (mLabel) { if (mWidget) {
gtk_label_get(GTK_LABEL(mLabel), &text); if (mLabel) {
aBuffer.SetLength(0); char* text;
aBuffer.Append(text); gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.Append(text);
}
} }
return NS_OK; return NS_OK;
} }

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

@ -58,6 +58,7 @@ public:
protected: protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow); NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void InitCallbacks(char * aName = nsnull); virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mLabel; GtkWidget *mLabel;
GtkWidget *mRadioButton; GtkWidget *mRadioButton;

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

@ -61,25 +61,40 @@ NS_METHOD nsScrollbar::CreateNative (GtkWidget * parentWindow)
mAdjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 100, 1, 25, 25)); mAdjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 100, 1, 25, 25));
switch (mOrientation) switch (mOrientation)
{ {
case GTK_ORIENTATION_HORIZONTAL: case GTK_ORIENTATION_HORIZONTAL:
mWidget = gtk_hscrollbar_new (mAdjustment); mWidget = gtk_hscrollbar_new (mAdjustment);
break; break;
case GTK_ORIENTATION_VERTICAL: case GTK_ORIENTATION_VERTICAL:
mWidget = gtk_vscrollbar_new (mAdjustment); mWidget = gtk_vscrollbar_new (mAdjustment);
break; break;
} }
gtk_widget_set_name (mWidget, "nsScrollbar"); gtk_widget_set_name (mWidget, "nsScrollbar");
gtk_signal_connect (GTK_OBJECT (mAdjustment), gtk_signal_connect (GTK_OBJECT (mAdjustment),
"value_changed", "value_changed",
GTK_SIGNAL_FUNC (handle_scrollbar_value_changed), GTK_SIGNAL_FUNC (handle_scrollbar_value_changed),
this); this);
gtk_signal_connect (GTK_OBJECT (mAdjustment),
"destroy",
GTK_SIGNAL_FUNC (DestroySignal),
this);
return NS_OK; return NS_OK;
} }
void
nsScrollbar::OnDestroySignal(GtkWidget* aGtkWidget)
{
if ((void*)aGtkWidget == (void*)mAdjustment) {
mAdjustment = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Query interface implementation // Query interface implementation
@ -276,15 +291,6 @@ PRBool nsScrollbar::OnResize(nsSizeEvent &aEvent)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
int nsScrollbar::AdjustScrollBarPosition (int aPosition) int nsScrollbar::AdjustScrollBarPosition (int aPosition)
{ {
int maxRange;
int sliderSize;
#if 0
XtVaGetValues (mWidget, XmNmaximum, &maxRange,
XmNsliderSize, &sliderSize,
nsnull);
int cap = maxRange - sliderSize;
return aPosition > cap ? cap : aPosition;
#endif
return 0; /* XXX */ return 0; /* XXX */
} }

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

@ -57,6 +57,7 @@ public:
protected: protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow); NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
private: private:
int mOrientation; int mOrientation;
@ -65,4 +66,4 @@ private:
int AdjustScrollBarPosition(int aPosition); int AdjustScrollBarPosition(int aPosition);
}; };
#endif // nsScrollbar_ #endif /* nsScrollbar_h__ */

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

@ -92,6 +92,10 @@ nsWidget::nsWidget()
nsWidget::~nsWidget() nsWidget::~nsWidget()
{ {
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWidget::~nsWidget:%p\n", this);
#endif
mIsDestroying = PR_TRUE; mIsDestroying = PR_TRUE;
if (nsnull != mWidget) { if (nsnull != mWidget) {
Destroy(); Destroy();
@ -116,6 +120,20 @@ NS_METHOD nsWidget::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect)
return NS_OK; return NS_OK;
} }
#ifdef DEBUG
void
nsWidget::IndentByDepth(FILE* out)
{
PRInt32 depth = 0;
nsWidget* parent = (nsWidget*)mParent;
while (parent) {
parent = (nsWidget*) parent->mParent;
depth++;
}
while (--depth >= 0) fprintf(out, " ");
}
#endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Close this nsWidget // Close this nsWidget
@ -124,7 +142,8 @@ NS_METHOD nsWidget::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect)
NS_IMETHODIMP nsWidget::Destroy(void) NS_IMETHODIMP nsWidget::Destroy(void)
{ {
#ifdef NOISY_WIDGET_DESTROY #ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWidget::Destroy:%p: isDestroying=%s widget=%p parent=%p\n", printf("nsWidget::Destroy:%p: isDestroying=%s widget=%p parent=%p\n",
this, mIsDestroying ? "yes" : "no", mWidget, mParent); this, mIsDestroying ? "yes" : "no", mWidget, mParent);
#endif #endif
@ -168,6 +187,21 @@ void nsWidget::OnDestroy()
} }
} }
gint
nsWidget::DestroySignal(GtkWidget* aGtkWidget, nsWidget* aWidget)
{
aWidget->OnDestroySignal(aGtkWidget);
return PR_TRUE;
}
void
nsWidget::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mWidget) {
mWidget = nsnull;
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Get this nsWidget parent // Get this nsWidget parent
@ -741,7 +775,7 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
{ {
GtkWidget *parentWidget = nsnull; GtkWidget *parentWidget = nsnull;
#if 0 #ifdef NOISY_DESTROY
if (aParent) if (aParent)
g_print("nsWidget::CreateWidget (%p) nsIWidget parent\n", g_print("nsWidget::CreateWidget (%p) nsIWidget parent\n",
this); this);
@ -786,6 +820,12 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
DispatchStandardEvent(NS_CREATE); DispatchStandardEvent(NS_CREATE);
InitCallbacks(); InitCallbacks();
// Add in destroy callback
gtk_signal_connect(GTK_OBJECT(mWidget),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
#ifdef NS_GTK_REF #ifdef NS_GTK_REF
if (aNativeParent) { if (aNativeParent) {
gtk_widget_unref(GTK_WIDGET(aNativeParent)); gtk_widget_unref(GTK_WIDGET(aNativeParent));
@ -804,16 +844,16 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsWidget::Create(nsIWidget *aParent, NS_METHOD nsWidget::Create(nsIWidget *aParent,
const nsRect &aRect, const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction, EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext, nsIDeviceContext *aContext,
nsIAppShell *aAppShell, nsIAppShell *aAppShell,
nsIToolkit *aToolkit, nsIToolkit *aToolkit,
nsWidgetInitData *aInitData) nsWidgetInitData *aInitData)
{ {
return(CreateWidget(aParent, aRect, aHandleEventFunction, return CreateWidget(aParent, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData, aContext, aAppShell, aToolkit, aInitData,
nsnull)); nsnull);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -822,16 +862,16 @@ NS_METHOD nsWidget::Create(nsIWidget *aParent,
// //
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsWidget::Create(nsNativeWidget aParent, NS_METHOD nsWidget::Create(nsNativeWidget aParent,
const nsRect &aRect, const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction, EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext, nsIDeviceContext *aContext,
nsIAppShell *aAppShell, nsIAppShell *aAppShell,
nsIToolkit *aToolkit, nsIToolkit *aToolkit,
nsWidgetInitData *aInitData) nsWidgetInitData *aInitData)
{ {
return(CreateWidget(nsnull, aRect, aHandleEventFunction, return CreateWidget(nsnull, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData, aContext, aAppShell, aToolkit, aInitData,
aParent)); aParent);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

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

@ -31,6 +31,11 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#ifdef DEBUG
#undef NOISY_DESTROY
#else
#undef NOISY_DESTROY
#endif
/** /**
* Base of all GTK+ native widgets. * Base of all GTK+ native widgets.
@ -122,6 +127,10 @@ class nsWidget : public nsBaseWidget
// are we a "top level" widget? // are we a "top level" widget?
PRBool mIsToplevel; PRBool mIsToplevel;
#ifdef DEBUG
void IndentByDepth(FILE* out);
#endif
protected: protected:
virtual void InitCallbacks(char * aName = nsnull); virtual void InitCallbacks(char * aName = nsnull);
@ -176,6 +185,8 @@ class nsWidget : public nsBaseWidget
virtual void OnButtonReleaseSignal(GdkEventButton * aGdkButtonEvent); virtual void OnButtonReleaseSignal(GdkEventButton * aGdkButtonEvent);
virtual void OnRealize(); virtual void OnRealize();
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
private: private:
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@ -207,6 +218,9 @@ private:
static gint RealizeSignal(GtkWidget * aWidget, static gint RealizeSignal(GtkWidget * aWidget,
gpointer aData); gpointer aData);
static gint DestroySignal(GtkWidget * aGtkWidget,
nsWidget* aWidget);
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// //
// GTK event support methods // GTK event support methods
@ -222,6 +236,7 @@ private:
void InitMouseEvent(GdkEventButton * aGdkButtonEvent, void InitMouseEvent(GdkEventButton * aGdkButtonEvent,
nsMouseEvent & anEvent, nsMouseEvent & anEvent,
PRUint32 aEventType); PRUint32 aEventType);
protected: protected:
GtkWidget *mWidget; GtkWidget *mWidget;
nsIWidget *mParent; nsIWidget *mParent;

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

@ -94,6 +94,10 @@ nsWindow::nsWindow()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
nsWindow::~nsWindow() nsWindow::~nsWindow()
{ {
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWindow::~nsWindow:%p\n", this);
#endif
mIsDestroyingWindow = PR_TRUE; mIsDestroyingWindow = PR_TRUE;
if (nsnull != mShell) { if (nsnull != mShell) {
Destroy(); Destroy();
@ -146,6 +150,11 @@ NS_METHOD nsWindow::RemoveTooltips()
NS_METHOD nsWindow::Destroy() NS_METHOD nsWindow::Destroy()
{ {
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWindow::Destroy:%p: isDestroyingWindow=%s widget=%p shell=%p parent=%p\n",
this, mIsDestroyingWindow ? "yes" : "no", mWidget, mShell, mParent);
#endif
NS_IF_RELEASE(m_nsIMenuBar); NS_IF_RELEASE(m_nsIMenuBar);
// Call base class first... we need to ensure that upper management // Call base class first... we need to ensure that upper management
@ -166,6 +175,15 @@ NS_METHOD nsWindow::Destroy()
return NS_OK; return NS_OK;
} }
void
nsWindow::OnDestroySignal(GtkWidget* aGtkWidget)
{
nsWidget::OnDestroySignal(aGtkWidget);
if (aGtkWidget == mShell) {
mShell = nsnull;
}
}
gint handle_delete_event(GtkWidget *w, GdkEventAny *e, nsWindow *win) gint handle_delete_event(GtkWidget *w, GdkEventAny *e, nsWindow *win)
{ {
win->SetIsDestroying( PR_TRUE ); win->SetIsDestroying( PR_TRUE );
@ -648,6 +666,14 @@ ChildWindow::ChildWindow()
{ {
} }
ChildWindow::~ChildWindow()
{
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("ChildWindow::~ChildWindow:%p\n", this);
#endif
}
PRBool ChildWindow::IsChild() const PRBool ChildWindow::IsChild() const
{ {
return PR_TRUE; return PR_TRUE;
@ -655,6 +681,10 @@ PRBool ChildWindow::IsChild() const
NS_METHOD ChildWindow::Destroy() NS_METHOD ChildWindow::Destroy()
{ {
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("ChildWindow::Destroy:%p \n", this);
#endif
// Skip over baseclass Destroy method which doesn't do what we want; // Skip over baseclass Destroy method which doesn't do what we want;
// instead make sure widget destroy method gets invoked. // instead make sure widget destroy method gets invoked.
return nsWidget::Destroy(); return nsWidget::Destroy();

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

@ -110,6 +110,8 @@ protected:
virtual gint OnDrawSignal(GdkRectangle * aArea); virtual gint OnDrawSignal(GdkRectangle * aArea);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
virtual void InitCallbacks(char * aName = nsnull); virtual void InitCallbacks(char * aName = nsnull);
@ -144,6 +146,7 @@ protected:
class ChildWindow : public nsWindow { class ChildWindow : public nsWindow {
public: public:
ChildWindow(); ChildWindow();
~ChildWindow();
virtual PRBool IsChild() const; virtual PRBool IsChild() const;
NS_IMETHOD Destroy(void); NS_IMETHOD Destroy(void);
}; };