GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Tue Jul 29, 2014 6:41 am

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: How is expose_event supposed to work?
PostPosted: Sun Dec 20, 2009 8:30 pm 
Offline
GTK+ Geek

Joined: Mon Jan 05, 2009 9:37 am
Posts: 68
Location: Austria
Dear All,

I got a bit confused about the expose_event callback, so I would like to ask for some directions. In short, my application has three windows, and on one of them, actions depend on which one of the other two was last active. My idea was to use a flag that I set through the expose_event callback, and then the value of that flag should indicate which window was the active one. I.e., I have written the following two functions
Code:
gboolean mainwindow_expose_cb(GtkObject *object, gpointer user_data) {
   printf("activated main\n");
        flag = MAIN;
   return(TRUE);
}

gboolean script_expose_cb(GtkObject *object, gpointer user_data) {
   printf("activated script\n");
        flag = SCRIPT;
   return(TRUE);
}


and hooked them up in glade to the GtkWidget expose_event signal. The problem is that if I have the main and the script windows open, and grab the script window, and move it with the mouse, "activated main" is printed, while the main window can't be exposed, for the simple reason that the other one is operated on. What is going on here? And what should I use to achieve what I outlined above?
Thanks,
Zoltán


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 20, 2009 9:14 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello.

Let me explain how things generally work.

Drawing is generally done on demand. This means that expose event is only triggered when windowing system needs some input. And even when expose event is triggered, you usually only need to redraw part of your GUI.

For example, let's assume that two windows are arranged like this:

Image

Window1 (red rectangle) represents your script window and window2 (blue rectangle) represents main window. In this sample scenario, we move window1 from position window1' (marked as transparent rectangle) into final position. During this move, window1 hasn't been obscured or otherwise damaged, which also means that windowing system does know how this window should be drawn. But during this move, parts of window2 that have been previously obscured are now visible. since windowing system doesn't know what should be there, it asks your application for some input and this is why your main window will receive expose event.

As you can see, expose events have nothing to do with active window. They are emitted when part of window needs to be redrawn.

Now to solving your problem. What you need to monitor is currently active window. Easiest way of doing this would be to monitor GtkWindow's "is-active" property, which will change when window is switched.

And since "notify" signal is not one of the best known ones, I'm providing some simple code to give you a kick start:
Code:
#include <gtk/gtk.h>

static void
monitor_active_window( GObject    *object,
                  GParamSpec *pspec,
                  gpointer    data )
{
   gboolean active;

   g_object_get( object, "is-active", &active, NULL );
   if( active )
      g_print( "Active: WINDOW%d\n", GPOINTER_TO_INT( data ) );
}

int
main( int    argc,
     char **argv )
{
   GtkWidget *window,
           *label;

   gtk_init( &argc, &argv );

   /* Window 1 */
   window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
   gtk_window_set_default_size( GTK_WINDOW( window ), 400, 300 );
   g_signal_connect( G_OBJECT( window ), "destroy",
                 G_CALLBACK( gtk_main_quit ), NULL );
   g_signal_connect( G_OBJECT( window ), "notify::is-active",
                 G_CALLBACK( monitor_active_window ),
                 GINT_TO_POINTER( 1 ) );

   label = gtk_label_new( "WINDOW1" );
   gtk_container_add( GTK_CONTAINER( window ), label );

   gtk_widget_show_all( window );

   /* Window 2 */
   window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
   gtk_window_set_default_size( GTK_WINDOW( window ), 400, 300 );
   g_signal_connect( G_OBJECT( window ), "destroy",
                 G_CALLBACK( gtk_main_quit ), NULL );
   g_signal_connect( G_OBJECT( window ), "notify::is-active",
                 G_CALLBACK( monitor_active_window ),
                 GINT_TO_POINTER( 2 ) );

   label = gtk_label_new( "WINDOW2" );
   gtk_container_add( GTK_CONTAINER( window ), label );

   gtk_widget_show_all( window );

   gtk_main();

   return( 0 );
}

Tadej


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 20, 2009 9:22 pm 
Offline
GTK+ Geek

Joined: Mon Jan 05, 2009 9:37 am
Posts: 68
Location: Austria
Hello Tadej,

Thanks a lot for this exhaustive reply! Things are now much clearer. I would like to suggest that we move your post to the example code section, or perhaps if you put it up on your blog, it would also be quite beneficial. I believe this is a subject that is not discussed at many places, therefore is obscure, and yet, it touches on the very core of GUI development.
Cheers,
Zoltán


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group