GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Destroy handler
Goto page 1, 2  Next
 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming
Author Message
genepi
Familiar Face


Joined: 12 Apr 2008
Posts: 6

PostPosted: Sun May 04, 2008 7:05 pm    Post subject: Destroy handler Reply with quote

Hi,

I wonder - is there a way, how I can make the window only hide after clicking the "shut" button (in the right top corner of the window) and not destroy?

Thanks
Back to top
cofcof
Familiar Face


Joined: 02 Apr 2008
Posts: 29

PostPosted: Sun May 04, 2008 11:17 pm    Post subject: Reply with quote

Hi Genepi

I have the same problem.

I don't know if it is possible; what I did is that
I removed the button with:

Code: (C)
1
2
3
4
5
gtk_window_set_deletable ()

void                gtk_window_set_deletable            (GtkWindow *window,
                                                         gboolean setting);

Quote:
By default, windows have a close button in the window frame. Some window managers allow GTK+ to disable this button. If you set the deletable property to FALSE using this function, GTK+ will do its best to convince the window manager not to show a close button. Depending on the system, this function may not have any effect when called on a window that is already visible, so you should call it before calling gtk_window_show().

On Windows, this function always works, since there's no window manager policy involved.


And then i make a "cancel" button on my windows such that when the user click on cancel, I hide the window.

This is not great but I didn't find better.

Cofcof
Back to top
genepi
Familiar Face


Joined: 12 Apr 2008
Posts: 6

PostPosted: Sun May 04, 2008 11:43 pm    Post subject: Reply with quote

I did the same thing - but my application is supposed to run under both Windows and Unix like systems, so I'm afraid that it's not going to work everywhere...
Back to top
cofcof
Familiar Face


Joined: 02 Apr 2008
Posts: 29

PostPosted: Mon May 05, 2008 12:37 am    Post subject: Reply with quote

genepi wrote:
I did the same thing - but my application is supposed to run under both Windows and Unix like systems, so I'm afraid that it's not going to work everywhere...


Hi again Genepi :)

I also compiled my application on windows, the trick works without problem.

I compilled it under mac, and since I couldn't installe a version of gtk+ older than 2.6.10 on it, it makes some problem since the set_deletable function is not in 2.6. As a consequence, i get some warning when I start my app and I get a problem if the user close one of my window that is not meant to be closed. My hope is that GTK will be soon natively available on mac, as the GTK project advertise it at the moment.


But that's true this is not a good solution anyway since it relies on the window manager. If you find a good solution please post it here cause I am interested too :)


CofCof
Back to top
Wolfgang
Familiar Face


Joined: 05 Feb 2008
Posts: 42

PostPosted: Mon May 05, 2008 7:16 am    Post subject: Reply with quote

First, you have to add this line after you created main window:
Code: (C)
1
g_signal_connect(mainwin, "delete_event", G_CALLBACK(gtk_main_quit_), NULL);

then define such function:
Code: (C)
1
2
3
4
5
gint gtk_main_quit_(GtkWidget *wnd, GdkEvent *event, gpointer user_data)
{
  gtk_widget_hide(wnd);
  return FALSE;
}

It hides your main window instead of destroing it. Isn't it?
Back to top
Micah Carrick
Never Seen the Sunlight


Joined: 21 Sep 2005
Posts: 465
Location: Portland, OR USA

PostPosted: Mon May 05, 2008 7:35 pm    Post subject: Reply with quote

From the GTK documentation:

Quote:
The ::delete-event signal is emitted if a user requests that a toplevel window is closed. The default handler for this signal destroys the window. Connecting gtk_widget_hide_on_delete() to this signal will cause the window to be hidden instead, so that it can later be shown again without reconstructing it.
Back to top
genepi
Familiar Face


Joined: 12 Apr 2008
Posts: 6

PostPosted: Mon May 05, 2008 11:54 pm    Post subject: Reply with quote

Neither of these two things are working.

I've tried this

Quote:

gint shut_error(GtkWidget *wnd)
{
gtk_widget_hide(wnd);
return FALSE;
}


my signal connect look like this:
glade_xml_signal_connect(gxml,"on_errorwin2_destroy", G_CALLBACK (shut_error));

This doesn't work.

When I replace gtk_widget_hide(wnd); by gtk_widget_hide_on_delete(wnd); it also doesn't work.
Back to top
Micah Carrick
Never Seen the Sunlight


Joined: 21 Sep 2005
Posts: 465
Location: Portland, OR USA

PostPosted: Tue May 06, 2008 12:14 am    Post subject: Reply with quote

You want to connect to the "delete-event" of the GtkWidget. This is a separate signal from the "destroy" of the GtkObject.

In glade, specify a handler name for the "delete-event" signal which you will find in the Signals tab under the GtkWidget expander. Let's say you specify 'on_window1_delete_event' as the handler in the glade file.

Then, you would connect that signal as follows:

Code: (C)
1
glade_xml_signal_connect (gxml,"on_window1_delete_event", G_CALLBACK (gtk_widget_hide_on_delete));
Back to top
cofcof
Familiar Face


Joined: 02 Apr 2008
Posts: 29

PostPosted: Tue May 06, 2008 12:16 am    Post subject: Reply with quote

Micah, thanks for the tip, I was looking for this one for a while :)

Genepi, here is what I did:

My callback function:
Code: (C)
1
2
3
4
5
void
on_window3_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
        gtk_widget_hide_on_delete (widget);
}


and i add an handler to the signal delete-event (I use Anjuta IDE so that I do it on the interface directly, but I guess if you connect your signal to your callback by hand, you should do something like (I haven't tested):

Code: (C)
1
2
g_signal_connect (window_3, "delete_event",
                             G_CALLBACK (on_window3_delete_event), window_3);


If I understood well what happened, if the delete-event is not connected, the windows is destroy by default.
If it is connected, then the action is defined by your callback.

CofCof
Back to top
Micah Carrick
Never Seen the Sunlight


Joined: 21 Sep 2005
Posts: 465
Location: Portland, OR USA

PostPosted: Tue May 06, 2008 3:18 am    Post subject: Reply with quote

For anyone interested, here is how you can think of it (simplified).

When the user clicks the 'x' in the title bar, the "delete-event" signal is triggered for the widget GtkWindow. The default handler is called which will then destroy the object triggering the "destroy" signal on that GtkObject.

However, if you specify a callback function to the "delete-event" signal, you can tell GTK based on your return value whether or not to call the default handler as well, known as propagating the signal. If you return TRUE from your callback function, then your callback function will be the only/last function for that signal. However, if you return FALSE then the default handlers for that "delete-event" signal will run.

There are some other signals for which this can apply. Pay attention to the prototype in the documentation. If it has a gboolean value as the return in the callback function prototype then it's probably a signal that you may need to stop propagation.

This is commonly used with a quit dialog in applications--such as in this example:
http://www.gtkforums.com/about672.html
Back to top
cofcof
Familiar Face


Joined: 02 Apr 2008
Posts: 29

PostPosted: Tue May 06, 2008 3:44 am    Post subject: Reply with quote

Thanks again Micah,

I never noticed that some callback function are void and some other return a bool.
Now I'll pay more attention.
Hence, I guess it is more correct to use

Code: (C)
1
2
3
4
5
6
gboolean
on_window3_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
        gtk_widget_hide_on_delete (widget);
        return(TRUE);
}


instead of what I wrote before (Though it did work too, but maybe it was just luck)
Back to top
Micah Carrick
Never Seen the Sunlight


Joined: 21 Sep 2005
Posts: 465
Location: Portland, OR USA

PostPosted: Tue May 06, 2008 3:58 am    Post subject: Reply with quote

The gtk_widget_hide_on_delete call is actually not neccessary if you are going to be defining your own callback. It's meant as a shortcut. You could simply have:

Code: (C)
1
2
3
4
5
6
gboolean
on_window3_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
        gtk_widget_hide_on_delete (widget);
        return(TRUE);
}





Just like with the "destroy" event, you can have your own callback function which calls gtk_main_quit() OR as a shortcut you can simply specify gtk_main_quit AS the callback function.
Back to top
Dadoo



Joined: 10 May 2008
Posts: 3

PostPosted: Sat May 10, 2008 12:43 am    Post subject: Reply with quote

I hope I'm not too late to this discussion, because I've been having the exact problem, all week. Here's my code:

Code: (C)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

GtkWidget *main_window,*options_window;

create_options_window()

{
GladeXML *options_xml = NULL;

    options_xml = glade_xml_new (GLADE_OPTIONS_WINDOW, NULL, NULL);
    if (!options_xml) {
        fprintf (stderr, "Can't open the options window description (%s).\n",
            GLADE_OPTIONS_WINDOW);
        exit (1);
        }

    options_window = glade_xml_get_widget (options_xml, "options_window");

    gtk_window_set_transient_for (GTK_WINDOW(options_window),
                                  GTK_WINDOW(main_window));
    g_signal_connect (G_OBJECT(options_window), "delete_event",
                G_CALLBACK(cancel_options), NULL);
/*
    glade_xml_signal_connect (options_xml, "on_options_window_delete_event",
                G_CALLBACK(cancel_options));
*/
   
glade_xml_signal_connect (options_xml, "on_confirm_options_clicked",
                 G_CALLBACK(confirm_options));
    glade_xml_signal_connect (options_xml, "on_cancel_options_clicked",
                G_CALLBACK(cancel_options));

    g_object_unref (options_xml);
}


The "g_signal_connect" works, but when I replace it with the "glade_xml_signal_connect" in the commented line, my "delete_event" handler isn't called, when I click the "X" in my options window. Any idea why?
Code: (C)
1
Back to top
Micah Carrick
Never Seen the Sunlight


Joined: 21 Sep 2005
Posts: 465
Location: Portland, OR USA

PostPosted: Sat May 10, 2008 3:31 pm    Post subject: Reply with quote

My first thought is that you perhaps forgot to specify that handler name in your Glade file? If you post that for your options window we'd be able to rule that out.
Back to top
Dadoo



Joined: 10 May 2008
Posts: 3

PostPosted: Mon May 12, 2008 10:05 pm    Post subject: Reply with quote

Quote:
My first thought is that you perhaps forgot to specify that handler name in your Glade file? If you post that for your options window we'd be able to rule that out.


Wow, I feel like an idiot, now, though I'd swear that was the first thing I thought would be the problem, and that I checked it about a million times. I am a complete GUI noob, though, and I'm learning so much, it's hard to keep everything straight. Sorry to have wasted your time.

Thanks for your help.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP