Frage

I want to detect when the user finished re-sizing or moving the GTK window. Basically an equivalent of WM_EXITSIZEMOVE in windows.

I have looked at GTK detecting window resize from the user and am able to detect size/location changes using the configure-event; however because of how my other code is architect I want to know when the resizing is done. Almost like ValueChanged instead of ValueChanging event.

I was thinking if i could find out is the mouse button is released or not and then try to detect if it was the last event I got. But can't find a way to do that either for a window object.

War es hilfreich?

Lösung

You could use a timeout function that gets called once the resizing is done. The timeout is in ms, you might want to play with the value to get a balance between the delay in calling resize_done and triggering it before the resize is really done.

#define TIMEOUT 250

gboolean resize_done (gpointer data)
{
  guint *id = data;
  *id = 0;
  /* call your existing code here */
  return FALSE;
}

gboolean on_configure_event (GtkWidget *window, GdkEvent *event, gpointer data)
{
  static guint id = 0;
  if (id)
    g_source_remove (id);
  id = g_timeout_add (TIMEOUT, resize_done, &id);
  return FALSE;
}

Andere Tipps

I implemented a solution (some would call it workaround) with PyGObject and Python 3. As Phillip Wood in this quesiton and ratchet freak in another question mentioned I also used a timer based solution.

In the example the size-allocate event is used to detected the beginning of the window resize. I assume the user drag the window border with its mouse here. There are other ways to detect a window resize event: see discussion here.

Next the event is disconnected and as a surrogate a timer event (GLib.timeout_add() with 500 milliseconds) is created handling the next stuff.

Here is the example code:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GLib


class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)

        # close event
        self.connect('delete-event', self._on_delete_event)

        # "resize" event
        self._connect_resize_event()

    def _connect_resize_event(self):
        self._timer_id = None
        eid = self.connect('size-allocate', self._on_size_allocated)
        self._event_id_size_allocate = eid

    def _on_delete_event(self, a, b):
        Gtk.main_quit()

    def _on_size_allocated(self, widget, alloc):
        print('EVENT: size allocated')

        # don't install a second timer
        if self._timer_id:
            return

        # remember new size
        self._remembered_size = alloc

        # disconnect the 'size-allocate' event
        self.disconnect(self._event_id_size_allocate)

        # create a 500ms timer
        tid = GLib.timeout_add(interval=500, function=self._on_size_timer)
        # ...and remember its id
        self._timer_id = tid

    def _on_size_timer(self):
        # current window size
        curr = self.get_allocated_size().allocation

        # was the size changed in the last 500ms?
        # NO changes anymore
        if self._remembered_size.equal(curr):  # == doesn't work here
            print('RESIZING FINISHED')
            # reconnect the 'size-allocate' event
            self._connect_resize_event()
            # stop the timer
            self._timer_id = None
            return False

        # YES size was changed
        # remember the new size for the next check after 500ms
        self._remembered_size = curr
        # repeat timer
        return True


if __name__ == '__main__':
    window = MyWindow()
    window.show_all()
    Gtk.main()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top