views:

1179

answers:

4

In GTK (or pygtk or gtkmm...)

How can I detect that an application window has been manually resized by the user, as is typically done by dragging the window's edge?

I need to find a way to differentiate manual resizes from resizes that originate from gtk, such as changes in window content.

A: 

In PyGTK, I've always watched for the expose_event for a window resize, then use the get_allocation method to get the new size.

eduffy
I'm looking at the GdkEventExpose structure...is it the send_event field that would tell me the user did it?
Shmoopty
Actually, you probably want event_configure, not event_expose... my bad. I think that's called for both moves and resizes, so you'll have to remember the previous size if that's all you're interested in.
eduffy
+1  A: 

Have you tried connecting to the GDK_CONFIGURE event?

Check out this example under the "Moving window" section. The example shows a callback doing something when the window is moved, but the configure event is a catch-all for moving, resizing and stack order events.

luke
A: 

You may be able to throw something together by using gdk_window_get_root_origin to get the top left corner of the window and gdk_window_get_geometry to get the width and height. Then you could hook a callback into the GDK_BUTTON_PRESS_MASK and check to see if the button press occurs near/on one of the edges of the window.

Of course, this seems quite hackish and it really bothers me that I couldn't find some simple way in the documentation for GdkWindow to do this. There is a gdk_window_begin_resize_drag function which really makes me think there's a cleaner way to do this, but I didn't see anything more obvious than my answer.

Eric
+1  A: 

I managed to pull this off by watching for size_allocate and size_request signals on the GtkWindow. If size_request ever got smaller, I called resize(1,1). If size_allocate was ever bigger than expected, I turned the system off.

One thing I made sure to handle was size_request returning big, then small, and having size_allocate be big and then small. I don't know if this is possible, but I fixed it by making sure to only decrease the expected values for size_allocate when I got a smaller size_allocate, not when I got a smaller size_request.

Make sure that your size_request handler comes after the base class' handler so that you get the right values. I did this by overriding the method and then calling the base class method first.

I've tried this in both 1 and 2 dimensions and it seems to work either way.

clahey