This doc:
https://www.fltk.org/doc-1.4/classFl__Window.html#acaf7d4846b4454911f7a2b4186d6c912
says decorated_h() "Returns the window height including any window
title bar and any frame added by the window manager." However, if you
call it in a Fl_Window overridden resize() method, it's actually the
*requested* height (presumably plus decorations), while this->h() is
the current height, which may become the requested height if the
superclass resize() is called.
This led to a bug for me because I use `int titlebar =
this->decorated_h() - this->h();` along with Fl::screen_work_area to
detect the size of the titlebar, and restrict the actual height it
passes on to Fl_Window::resize so it won't exceed the screen height -
menubar - titlebar. However on X11, since decorated_h() has already
changed to the requested height, the subtraction no longer works!
This doesn't seem to happen on OSX.
So... I think it would be proper for X11 to do like OSX and for
decorated_h() to be the current height plus decoration. Alternately,
if there's a better way to detect the window titlebar height I'm all
ears! For the moment I'm going to put the titlebar height in a static
variable, assuming it never changes. Interestingly, this is probably
only reliable for X11, since it seems to send a bunch of resize
requests when the window is displayed, while OSX doesn't seem to send
any, but of course I only need the workaround on X11, so it works out
:)
The reason I have to do this is that the app can receive resize
requests from inside itself, simpler apps that only get resizes from
the OS can rely on the OS enforcing the screen fit rules.
I assume decorated_w() has the same problem though I don't check it
since OSX doesn't have decoration on the side.
Oh and this is a totally different thing, but I recently fixed a bug
where I accidentally called Fl_Window::resize for the superclass
instead of Fl_Double_Window. That was fine on OS X where they are the
same, but led to messed up drawing on X11. It would be nice to remove
the two kinds of window, assuming non-double-buffered windows are
truly obsolete.
Here's a little program to demonstrate the problem. Run it, then have
your window manager maximize the window vertically:
#include <iostream>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
#include <FL/Fl.H>
class Bug : public Fl_Window {
public:
Bug(int x, int y, int w, int h)
: Fl_Window(x, y, w, h), box(0, 0, w, h)
{
this->resizable(this);
box.box(FL_FLAT_BOX);
box.color(FL_WHITE);
}
void resize(int x, int y, int w, int h) override {
std::cout << "BEFORE h:" << this->h() << " decorated_h:"
<< this->decorated_h() << '\n';
Fl_Window::resize(x, y, w, h);
std::cout << "AFTER h:" << this->h() << " decorated_h:"
<< this->decorated_h() << '\n';
}
Fl_Box box;
};
int main()
{
Bug win(200, 200, 200, 200);
win.show();
Fl::run();
return 0;
}