[OS X] How to receive window resize events?

373 views
Skip to first unread message

Will B

unread,
Mar 31, 2018, 4:27:22 PM3/31/18
to fltk.general
Hello all,

I'm using FLTK 1.3.4-2 on OS X 10.6.8.

On Linux and BSD, when the user maximizes, restores or otherwise resizes the top-level window, I receive an event in my callback for add_handler.  On OS X (10.6.8, at least) I am receiving *zero* events when the top-level window geometry or position changes.  This stinks because all of the child widgets are still arranged as if the window size never changed, which looks incredibly bad to the user.

I have tried add_system_handler and it indeed receives events for top-level window resizes and position changes, but it also receives events for mouse movement, keyboard presses and when a butterfly's wings flutter too close to the computer! :-P  It's a fire-hose amount of events, which would fire all the time, and my app would have to deal with all of that while trying to do its main job with decent performance.

Do any of you all have any suggestions on how to know when the top-level window geometry changes?  Admittedly, I'm not super-well-versed on Mac-centric development, so when I tried including NSEvents.h and tried to compile, it was an avalanche of errors about objective-c stuff in a C++ app.

Thank you! :-)

Evan Laforge

unread,
Mar 31, 2018, 4:32:37 PM3/31/18
to fltkg...@googlegroups.com
I get them in my OS X app, but I pick them up in the resize() method.
What happens if you override the window's resize() to record the
change?

Also doesn't fltk itself handle adjusting the child layout automatically?
> --
> You received this message because you are subscribed to the Google Groups
> "fltk.general" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to fltkgeneral...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Will B

unread,
Mar 31, 2018, 4:44:06 PM3/31/18
to fltk.general

Hi,

The only resize() I see is for resizing the window programmatically.  I'm not seeing a resize event that I can override like when you override handle().

Thanks :-)

Evan Laforge

unread,
Mar 31, 2018, 4:53:08 PM3/31/18
to fltkg...@googlegroups.com
> The only resize() I see is for resizing the window programmatically. I'm
> not seeing a resize event that I can override like when you override
> handle().

All resizes go through the resize() method, whether programmatically
or the OS telling about a drag. So if you override your
MyWindow::resize to call print and then pass on to
Fl_Window::resize(x, y, w, h) then you should get a lot of output when
you drag the window around. Note I'm not saying *call* resize, I'm
saying override it so you can intercept the new values.

There might be an event too for all I know, but I generate my own
event from resize() and it works for me :)

Will B

unread,
Mar 31, 2018, 5:11:57 PM3/31/18
to fltk.general
On Saturday, March 31, 2018 at 1:53:08 PM UTC-7, qdunkan wrote:
All resizes go through the resize() method, whether programmatically
or the OS telling about a drag.  So if you override your
MyWindow::resize to call print and then pass on to
Fl_Window::resize(x, y, w, h) then you should get a lot of output when
you drag the window around.  Note I'm not saying *call* resize, I'm
saying override it so you can intercept the new values.

Yeah!  Works great!  Thank you so much, qdunkan! :-D
 

Greg Ercolano

unread,
Mar 31, 2018, 5:14:16 PM3/31/18
to fltkg...@googlegroups.com
Yes, overriding resize() for the widget in question is the way
to go.

AFAIK, only resize() clearly communicates at the exact point in time
the 4 values of the 'new' widget size vs. the 'old' current size
are about to change, giving you a chance to adjust before the change
is applied to the current and child widgets.

You could call handle() from your resize() method with a user-defined
event if you really need to catch things there -- and then you can
control the timing of the event delivery; before or after changes
applied to the current widget, before or after changes to children
or particular children, etc.
Message has been deleted

Will B

unread,
Mar 31, 2018, 5:31:23 PM3/31/18
to fltk.general
On Saturday, March 31, 2018 at 2:14:16 PM UTC-7, Greg Ercolano wrote:
        Yes, overriding resize() for the widget in question is the way
        to go.

        AFAIK, only resize() clearly communicates at the exact point in time
        the 4 values of the 'new' widget size vs. the 'old' current size
        are about to change, giving you a chance to adjust before the change
        is applied to the current and child widgets.

        You could call handle() from your resize() method with a user-defined
        event if you really need to catch things there -- and then you can
        control the timing of the event delivery; before or after changes
        applied to the current widget, before or after changes to children
        or particular children, etc.

Thanks Greg.  I just needed a way to know that the window geometry had changed, and thankfully overriding resize() works, so thanks again qdunkan!

For internet searchers, this is a simple example of overriding resize().  When running this myself, width and height seem to be accurate when resizing, but when I move the window, the width and height appear to be wrong.  They eventually display the default width and height if you move the window enough.

/* Fl_Double_Window events test */
#include <FL/x.H>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>

#include <iostream>


/* subclassed Fl_Double_Window */
class MyWin : public Fl_Double_Window
{
public:
   
MyWin() : Fl_Double_Window(1024, 768) {resizable(this);};
private:    
   
void resize (int X, int Y, int W, int H);
};


/* handle resize events */
void MyWin::resize (int X, int Y, int W, int H)
{
    std
::cout << "resize: "
       
<< X << ", "
       
<< Y << ", "
       
<< W << ", "
       
<< H << "\n";
}


/* main program */
int main (int argc, char **argv)
{
   
// create new window
   
MyWin* win = new MyWin();
    win->show(argc, argv);
   
   
return Fl::run();
}

Albrecht Schlosser

unread,
Apr 1, 2018, 4:23:30 AM4/1/18
to fltkg...@googlegroups.com
On 31.03.2018 23:31 Will B:
>
> For internet searchers, this is a simple example of overriding
> resize().  When running this myself, width and height seem to be
> accurate when resizing, but when I move the window, the width and height
> appear to be wrong.  They eventually display the default width and
> height if you move the window enough.

I can't confirm this (running under Linux).

Anyway, your example code is incomplete. You should *always* call the
base class' resize() method, otherwise child widgets won't be resized. I
don't know if this can have anything to do with the behavior observed by
you, but, as you wrote, "For internet searchers..." I wanted to mention it:

/* handle resize events */
void MyWin::resize (int X, int Y, int W, int H)
{
std::cout << "resize: "
<< X << ", "
<< Y << ", "
<< W << ", "
<< H << "\n";
Fl_Double_Window::resize(X, Y, W, H); // <-- ADD THIS !
}

Depending on what you want to achieve, it can be enough to call
Fl_Window::resize() or Fl_Group::resize() instead, but that is another
story.

OTOH, if you want to do the widget resizing yourself, you might want to
call only Fl_Widget::resize() which will update the widget (in this case
the window) coordinates and sizes, then resize the children yourself,
like so:

/* handle resize events */
void MyWin::resize (int X, int Y, int W, int H)
{
std::cout << "resize: "
<< X << ", "
<< Y << ", "
<< W << ", "
<< H << "\n";
Fl_Widget::resize(X, Y, W, H); // adjust widget coord's and sizes

if (children()) {
// Add code to resize child widgets here:

...
}
}

Will Brokenbourgh

unread,
Apr 2, 2018, 7:20:41 PM4/2/18
to fltkg...@googlegroups.com
On Sun, Apr 1, 2018 at 1:23 AM, Albrecht Schlosser <Albrech...@online.de> wrote:
Anyway, your example code is incomplete. You should *always* call the base class' resize() method, otherwise child widgets won't be resized. I don't know if this can have anything to do with the behavior observed by you, but, as you wrote, "For internet searchers..." I wanted to mention it

Sorry :-(
Reply all
Reply to author
Forward
0 new messages