RE: [fltk.general] Window size decreasing

175 views
Skip to first unread message

MacArthur, Ian (Selex ES, UK)

unread,
Nov 25, 2014, 11:40:02 AM11/25/14
to fltkg...@googlegroups.com

> I'm building my application on a new Windows development machine with
> Windows 8.1 (instead of previous Windows 7) and VS2013 (instead of
> previous VS2008) but with the same fltk-1.3.0 source as before.

You need to upgrade to 1.3.3, or the recent weekly snapshots.

Or switch to using mingw, or an older version of VC.

Or, use a bin editor to set the executable type to something older than Win7...


Basically, newer versions of the VS tools, running the exe on Win7 and later, will do some rather odd things to the window border settings.

I think this is fixed (or worked around at any rate) for fltk-1.3.3, but 1.3.0 is pretty old now and it has no idea what Win7, Win8.x or VS2013 are...



Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

ekstrand...@gmail.com

unread,
Nov 28, 2014, 4:34:08 AM11/28/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Thanks Ian, 1.3.3 works much better!

ekstrand...@gmail.com

unread,
Dec 2, 2014, 4:35:42 AM12/2/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
...or least I though so at first. :-(

It turns out the problem is still there even with 1.3.3. Just closing and opening my windows in Fluid shows the problem, the window size decreases each time! To reproduce, run Fluid in Windows 8.1, create a window, close it (e.g. with Escape), open it again (e.g. by double-clicking the window in the list). Do this several times and you'll see the window size decreasing each time. I don't know of any differences in window border sizes etc. between Windows 8 and Windows 8.1, maybe FLTK 1.3.3 doesn't support Windows 8 at all?

Does someone else have this problem? Right now, FLTK is useless for me here and I can't build a new release of our software...

ekstrand...@gmail.com

unread,
Dec 2, 2014, 4:46:28 AM12/2/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
BTW, the problem still appears with the latest weekly snapshots. And maybe it's not reproduced by simply running Fluid, it probably has to be built with VS2013 as well. I really hope someone has a solution to this one, it's a showstopper for us right now.

Edzard Egberts

unread,
Dec 2, 2014, 5:15:12 AM12/2/14
to fltkg...@googlegroups.com
ekstrand...@gmail.com wrote:
> it probably has to be built with VS2013 as well.

This makes sense, Microsoft Products don't favour programming, but
working around. ;o)

> I really hope someone has a solution to this
> one, it's a showstopper for us right now.

There are some things you could try:

Does the method size_range() restrict shrinking of window?

There is a protected member

• void force position (int force)
Sets an internal flag that tells FLTK and the window manager to honor
position requests.

Maybe it helps to set this.

Also there are members storing the initial sizes - no_fullscreen_w and
no_fullscreen_h. After calling show() you could call resize() and use
these values to restore original size.

Or you can try to use MinGW...

MacArthur, Ian (Selex ES, UK)

unread,
Dec 2, 2014, 5:43:31 AM12/2/14
to fltkg...@googlegroups.com
> BTW, the problem still appears with the latest
> weekly snapshots. And maybe it's not reproduced
> by simply running Fluid, it probably has to be
> built with VS2013 as well. I really hope someone
> has a solution to this one, it's a showstopper for
> us right now.

I think this problem is related to this STR, though not "the same" problem exactly.

http://www.fltk.org/str.php?L3061

There was a longish thread related to this in fltk.general too.

The upshot was that if you are on Win7 or Win8, and if you compile with VS2102 or later, and if you have the compiler configured so that it sets exe type MajorSubsystemVersion = 6 in the optional header of the image, then you get the aberrant behaviour.

Note that if you build with the MajorSubsystemVersion to 5 or less, you get the "old" behaviour and all is well.

At least with VS2012 you can set that up in a menu somewhere... um... greentea101 says:

"In Visual C++ 2012, the subsystem version is controlled by the setting "Configuration Properties->General->Platform Toolset" from the project settings. Alternatively, it can also be changed from "Linker->System->Minimum Required Version"."


You can also edit the MajorSubsystemVersion and MinorSubsystemVersion data "after the fact" by editing the PE header with a tool like CFF Explorer, to the same effect.

Or use the a compiler that does not set the subsystem version data...


FWIW, I can't test for this bug, I don't have access to Win8 at all, and can not reconfigure the Win7 machines I do have...

greentea101

unread,
Dec 2, 2014, 8:20:22 AM12/2/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
I seriously doubt that this is related to http://www.fltk.org/str.php?L3061, but I could be wrong. I'd love to take a look at the problem if the OP provided some mock code that reproduces it. I already have access to a Win8.1 environment, and I'm willing to download and install VS2013.

MacArthur, Ian (Selex ES, UK)

unread,
Dec 2, 2014, 8:30:20 AM12/2/14
to fltkg...@googlegroups.com
> I seriously doubt that this is related to
> http://www.fltk.org/str.php?L3061, but I could
> be wrong.

OK: I agree it is not "the same" as 3061, just that the symptoms sound similar, (didn’t happen with older VS compiler, does now, affects window sizes, etc.)

The OP has the recent tarballs so the fix for 3061 is in, and they still see the problem...

> I'd love to take a look at the problem
> if the OP provided some mock code that reproduces
> it. I already have access to a Win8.1 environment,
> and I'm willing to download and install VS2013.

A volunteer is worth ten pressed men...

I'm not sure, but I had the impression from the thread that fluid itself was exhibiting the problem, if they repeatedly opened / closed (or perhaps minimized / restored) the windows. Or I may be entirely mistaken.

But as I say, I can’t reproduce here, so not sure what else might be in play!

Cheers,
--
Ian

ekstrand...@gmail.com

unread,
Dec 2, 2014, 8:34:40 AM12/2/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
I tried to change toolset to v120_xp in VS2013, and it actually seems to fix the problem, at least in Fluid. But it doesn't seem like a future-proof solution.

I also tried the size_range-solution and it actually also seems to fix it as well - but I would like the user to be able to resize the windows, so I don't think it's a way forward either.

I'd be grateful if you tried to reproduce it, greentea. Seems like the simplest way is to build Fluid in VS2013, start it and create a window which you close and then reopen again. Close with Escape and reopen with double-click to reach a fast result. Looking forward to your feedback.

Albrecht Schlosser

unread,
Dec 2, 2014, 10:10:48 AM12/2/14
to fltkg...@googlegroups.com
On 02.12.2014 14:34 ekstrand.andreas wrote:
> I tried to change toolset to v120_xp in VS2013, and it actually seems to
> fix the problem, at least in Fluid. But it doesn't seem like a
> future-proof solution.
>
> I also tried the size_range-solution and it actually also seems to fix
> it as well - but I would like the user to be able to resize the windows,
> so I don't think it's a way forward either.
>
> I'd be grateful if you tried to reproduce it, greentea. Seems like the
> simplest way is to build Fluid in VS2013, start it and create a window
> which you close and then reopen again. Close with Escape and reopen with
> double-click to reach a fast result. Looking forward to your feedback.

I have a suspicion what to look for, but I can't test it:

IIRC fluid stores the window sizes and tries to restore the same window
sizes when it is started again. If we assume that the requested window
size and the real window size are different (maybe by a few pixels
border width) then this would explain the effect. For instance open a
window with size 100x100 -> actually gets a "net size" of 96x96, and
this size is stored. Next time open with 96x96, and so on.

This could affect all programs that store the window size and try to
reopen the window with the same size.

Just a guess though, but I hope it helps.

ekstrand...@gmail.com

unread,
Dec 2, 2014, 10:23:15 AM12/2/14
to fltkg...@googlegroups.com
Yes, this also seems to be a problem - the windows are too small when first opened in FLTK as well. So it could be a different problem that what I'm seeing in my windows created in my code? This small ugly example shows my problem (keep pressing the Test button to hide and show the window, its size should decrease):

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>

Fl_Window *win2 = NULL;

void cb(Fl_Widget *widget, void *data)
{
 
if (win2->shown())
    win2
->hide();
 
else
    win2
->show();
}

int main(int argc, char **argv)
{
 
Fl_Window *win = new Fl_Window(100, 100, 100, 100);

 
Fl_Button *button = new Fl_Button(5, 5, 50, 20, "test");
  button
->callback(reinterpret_cast<Fl_Callback *>(cb));

  win
->add(button);
  win
->show();

  win2
= new Fl_Window(300, 100, 100, 100);
 
Fl_Group *group = new Fl_Group(0, 0, 100, 100);
  win2
->add_resizable(*group);
  win2
->show();

 
Fl::run();
}

A.J. bonnema

unread,
Dec 2, 2014, 10:31:11 AM12/2/14
to fltkg...@googlegroups.com
On 02-12-14 16:23, ekstrand...@gmail.com wrote:
> Yes, this also seems to be a problem - the windows are too small when
> first opened in FLTK as well. So it could be a different problem that
> what I'm seeing in my windows created in my code? This small ugly
> example shows my problem (keep pressing the Test button to hide and
> show the window, its size should decrease):
>
Not so in my environment it remains unaltered in size. I run Fedora 20
probably with fltk-1.3.2. The window stays the same size.

P.S. What is annoying though is that if I press the button with the
mouse of course it gains focus. If I subsequently use the space bar to
press the button, the button loses focus. I was hoping to repeatedly use
the space bar to press the button: alas.

Is that what one would expect? I expected the space bar not to affect
focus. Maybe the focus automatically went to the other window because it
was shown anew?

Guus.

MacArthur, Ian (Selex ES, UK)

unread,
Dec 2, 2014, 10:56:48 AM12/2/14
to fltkg...@googlegroups.com
> Not so in my environment it remains unaltered in size. I run Fedora 20
> probably with fltk-1.3.2. The window stays the same size.

Hi Guus,

Yes, this is a problem that is specific to Windows, IF you are running Win7 or Win8, AND you have compiled fltk with VS2012 or VS2013 AND the susbsystem version in the exe is set to 6 or higher. We think...




> P.S. What is annoying though is that if I press the button with the
> mouse of course it gains focus. If I subsequently use the space bar to
> press the button, the button loses focus. I was hoping to repeatedly
> use
> the space bar to press the button: alas.
>
> Is that what one would expect? I expected the space bar not to affect
> focus. Maybe the focus automatically went to the other window because
> it
> was shown anew?

You probably need to try 1.3.3 or the recent weeklies. ISTR that Lauri did some work on window focus issues that sound similar to what you describe.

MacArthur, Ian (Selex ES, UK)

unread,
Dec 2, 2014, 10:59:30 AM12/2/14
to fltkg...@googlegroups.com
> Yes, this also seems to be a problem - the windows
> are too small when first opened in FLTK as well.

Hmm, that's interesting; the issue addressed in STR 3061 was about the size of windows under Windows, and how the width of the border decorations is calculated, on "recent" Windows variants that set the border decorations in some "different" way...

Albrecht Schlosser

unread,
Dec 2, 2014, 11:23:10 AM12/2/14
to fltkg...@googlegroups.com
On 02.12.2014 16:59 MacArthur, Ian (Selex ES, UK) wrote:
>> Yes, this also seems to be a problem - the windows
>> are too small when first opened in FLTK as well.
>
> Hmm, that's interesting; the issue addressed in STR 3061 was about the size of windows under Windows, and how the width of the border decorations is calculated, on "recent" Windows variants that set the border decorations in some "different" way...

I believe this is all one cause. The problem was (IIRC) that the border
calculation was different, in a way that the border was inside the area
we just wanted the window to be. So if we requested a window size
100x100 and if the border size was enlarged by 2 (border padding) and if
this was "inside" the window area, then the net window size is only
96x96. If this size is then reported internally, then this might cause
what Andreas describes.

FWIW, a good pixel measuring tool is Greg's flruler (thanks, Greg), see
here:
http://seriss.com/people/erco/fltk/flruler/

When I start the given test program (built with MinGW under Windows 8.1)
I can see a border size of about 8 pixels width, but the net window size
(its drawable area) is 100x100 as requested. Maybe this is different if
compiled with VS2013. Can anybody check this?

If this was true, then we could probably fix it by _adding_ the border
padding to the window size when we show() it, so that Windows gives us a
window with a drawable size as requested, but then we'd have to deduct
the border size after show() again. Or something like this. Maybe.

greentea101

unread,
Dec 2, 2014, 12:30:19 PM12/2/14
to fltkg...@googlegroups.com
Well, I was able to reproduce the behavior in Win8.1 and VS2013, with the test code the OP provided. It seems that the dimensions of the window change every time after calling win2->show(). To be clear, that means that win2->x(), win2->y(), win2->w() and win2->h() return abnormal values. I am currently investigating. Please remain calm and await further input, I'm on the case. :P

greentea101

unread,
Dec 2, 2014, 3:37:28 PM12/2/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
I've been debugging with some success, but I kind of reached a dead end. Like the OP mentioned, the window position and dimensions seem to change inside Fl_X::make() (Fl_win32.cxx), immediately after the call to ShowWindow(). I don't understand how that's possible. How could the call to ShowWindow() affect the Fl_Window object?

For what it's worth, here are the new values after ShowWindow() is called: x+4, y+4, w+24, h-8. The x & y coordinates and the height change with each call to show(), but the width remains a constant w+24 for whatever reason. The value 4 is what GetSystemMetrics(SM_CXSIZEFRAME) returns, and I'm betting my favorite body part that 8 is 2*GetSystemMetrics(SM_CYSIZEFRAME). This behavior is somewhat different from what the OP reported (the width doesn't decrease for me, and the position and size of the Fl_Window are changed). For the record, I'm using FLTK 1.3.3, Visual Studio 2013 Community Edition with Update 4, and of course Win8.1.

This is definitely related to the aforementioned STR, the only question is how. I don't think I can devote any more time to this today, so that's all I've got for now.

greentea101

unread,
Dec 2, 2014, 7:01:16 PM12/2/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Sorry to spam with a 3rd post in a row, but this problem has been haunting me and I couldn't stay away.

Andreas, it turns out that the only reason width wasn't decreasing for me, is because I was constructing the Fl_Window with the width of 100, which seems to be the minimum. After I changed it to 200, it did decrease by 8 with each show(), until it reached 124 and stopped there. So now the only difference between my testing and your report, would be the fact that in my case the x_, y_, w_ and h_ members of the Fl_Window object do change, while in your case they don't (unless I'm misunderstanding your post).

I am able to counteract the effect by adding the line "win2->resize(win2->x() - 4, win2->y() - 4, win2->w() + 8, win2->h() + 8);" after each "win2->show();". The "real" fix would be to go into Fl_X::fake_X_wm() and replace:

if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
    ret
= 2;
    bx
= GetSystemMetrics(SM_CXSIZEFRAME);
   
by = GetSystemMetrics(SM_CYSIZEFRAME);
} else {
...

with:

if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
    ret
= 2;
   
int padding = GetSystemMetrics(SM_CXPADDEDBORDER);
    NONCLIENTMETRICS ncm
;
    ncm
.cbSize = sizeof(NONCLIENTMETRICS);
   
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
    bx
= GetSystemMetrics(SM_CXFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
   
by = GetSystemMetrics(SM_CYFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
} else {
...

But that only works when using the v120 toolset (and screws things up when using v120_xp). By the way, the problem also happens for me in Win7 with FLTK 1.3.2 and VS2012. I'll be back at this tomorrow with a clear head, but I hope this is helpful.

MacArthur, Ian (Selex ES, UK)

unread,
Dec 3, 2014, 4:39:42 AM12/3/14
to fltkg...@googlegroups.com
> I tried to change toolset to v120_xp in VS2013, and
> it actually seems to fix the problem, at least in Fluid.
> But it doesn't seem like a future-proof solution.

Perhaps not a solution, but a credible workaround for now, in that you can proceed with work on your app and it will work.

(Sometimes, especially with MS, a credible workaround is about the best you can hope for!)

As regards this particular problem, it seems to me (and I'd welcome clarification on this point) that MS are allowing the window decorations to extend into the client window area, for apps that report themselves as being "recent enough".

Is that a correct interpretation?

If so, that seems like a very odd choice for them to make; historically, the window decoration is not allowed to impinge on the client area at all, and that is the assumption we make in all our window calculations.

If they are allowing the decorations to "steal" a part of the client area, that seems like a very tricky thing for us to deal with reliably:

I guess we'd need (at runtime) to detect that the window decoration was of a style that *wants* to steal some client area, and then request a suitably larger client area to compensate, so that the "usable" client area remains the same as before.

Then what do we store internally? I guess we need to store the "usable" client area, which is equivalent to what we have at present, rather than the "extended" client area?

Hmm... I dunno...

--
Ian

MacArthur, Ian (Selex ES, UK)

unread,
Dec 3, 2014, 4:41:01 AM12/3/14
to fltkg...@googlegroups.com
> Sorry to spam with a 3rd post in a row,
> but this problem has been haunting me
> and I couldn't stay away.

We welcome the input; keep it coming!

Cheers,
--
Ian

Albrecht Schlosser

unread,
Dec 3, 2014, 5:54:02 AM12/3/14
to fltkg...@googlegroups.com
On 03.12.2014 10:39, MacArthur, Ian (Selex ES, UK) wrote:

> If they are allowing the decorations to "steal" a part of the client area, that seems like a very tricky thing for us to deal with reliably:
>
> I guess we'd need (at runtime) to detect that the window decoration was of a style that *wants* to steal some client area, and then request a suitably larger client area to compensate, so that the "usable" client area remains the same as before.

That was my impression as well. But let's wait what greentea comes up
with...

> Then what do we store internally? I guess we need to store the "usable" client area, which is equivalent to what we have at present, rather than the "extended" client area?

User code would have to see the "real" or "net" client area, i.e. the
smaller value in x(), y(), w(), and h().

Depending on how "static" the amount of the "stolen" area would be, we
could either use a global storage (if we can cache the padding width),
an additional member variable per window, or query the system every time
we show a window. I imagine that borderless windows would behave
differently, so we might want to store the border difference per window,
maybe when we show it for the first time. If we assume that users can
change the padding size during runtime then we'd have to query the
system before show(), but I hope that we can cache the value to avoid
this additional runtime overhead per show(), even if it seems negligible.

Looking forward to greentea's results...

Albrecht Schlosser

unread,
Dec 3, 2014, 7:53:23 AM12/3/14
to fltkg...@googlegroups.com
On 03.12.2014 01:01, 'greentea101' via fltk.general wrote:
> Sorry to spam with a 3rd post in a row, but this problem has been
> haunting me and I couldn't stay away.

No problem, we like to be informed, and we appreciate your help.

> ... The "real" fix would be to go into
> Fl_X::fake_X_wm() and replace:
>
> |
> if(w->size_range_set &&(w->maxw !=w->minw ||w->maxh !=w->minh)){
> ret =2;
> bx =GetSystemMetrics(SM_CXSIZEFRAME);
> by=GetSystemMetrics(SM_CYSIZEFRAME);
> }else{
> ...
> |
>
> with:
>
> |
> if(w->size_range_set &&(w->maxw !=w->minw ||w->maxh !=w->minh)){
> ret =2;
> intpadding =GetSystemMetrics(SM_CXPADDEDBORDER);
> NONCLIENTMETRICS ncm;
> ncm.cbSize =sizeof(NONCLIENTMETRICS);
> SystemParametersInfo(SPI_GETNONCLIENTMETRICS,0,&ncm,0);
> bx =GetSystemMetrics(SM_CXFIXEDFRAME)+(padding ?padding
> +ncm.iBorderWidth :0);
> by=GetSystemMetrics(SM_CYFIXEDFRAME)+(padding ?padding +ncm.iBorderWidth
> :0);
> }else{
> ...
> |

Looks like something we could use. Maybe we can cache the padding width
somehow so that we don't need to query the system each time we show the
window?

> But that only works when using the v120 toolset (and screws things up
> when using v120_xp). By the way, the problem also happens for me in Win7
> with FLTK 1.3.2 and VS2012.

That's interesting. I don't have Visual C++ 2012 installed yet (only
VC++ 2010 Express) on my Win7 system. Do you think I can see the effect
if I install VC++ 2012/2013 Express? What do I need to do to see the
problem? What system setup, what VC++ setup? Can you describe?

> I'll be back at this tomorrow with a clear
> head, but I hope this is helpful.

Very much, and very much appreciated! Thanks!

greentea101

unread,
Dec 3, 2014, 2:53:22 PM12/3/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Ok, I'll try to summarize the situation as I see it, just to crystallize my thoughts, and to make sure we're all on the same page.

The FLTK window is just the client area of the WIN32 WM window, while the WM window also includes the decorated part. All WIN32 API functions that deal with window coordinates and dimensions expect the measurements of window decorations to be included in the arguments passed (there are also functions for the client area, but that's irrelevant).

So if you ask WIN32 to create a window of size 100x100, the window decorations + the client area will be drawn in that 100x100 pixel area. That means that when FLTK has to create a 100x100 sized window, it needs to calculate what the size of the WIN32 window is going to be with the decorations included, so it can pass those values to WIN32. That's what the primary role of Fl_X::fake_X_wm() seems to be. That function is called by Fl_X::make() (among others), which uses it to obtain the measurements of the window decorations (border width and titlebar height). Fl_X::make() then uses those measurements to calculate the correct values to pass to the CreateWindowExW API, so that a WIN32 window with a client area of 100x100 is created.

The problem addressed by STR#3061, was that Fl_X::fake_X_wm() was not calculating the border width correctly for all possible cases. Specifically, the calculation did not take into account border padding, which becomes a factor in the special case when the subsystem version of the PE image is 6.0 or higher. That resulted in too low width and height passed to CreateWindowExW(), which caused the window manager to draw the right & bottom borders over the "FLTK window" (through no fault of the WM, it simply did what it was asked).

I don't remember all I did back I was investigating that problem, but after testing I concluded that the special case is limited to non-resizable windows. Now it seems that that's not true, or at least not entirely true, so I'm going to have to re-evaluate that, and try to gain a new understanding of the situation. I have not yet done anything towards that end, but I intend to during the coming days (weeks?), and I hope to eventually come up with an adequate solution.

If anyone wants to reproduce the problem, just use the OP's test code, and compile it into an executable image that has MajorSubsystemVersion = 6. You can do that by using the v110 toolset with VS2012, or v120 with VS2013 (those should be the defaults, so you shouldn't need to change them). Alternatively, just use any compiler, and edit the executable image with CFF Explorer (MajorSubsystemVersion is in the "Optional Header" section).

MacArthur, Ian (Selex ES, UK)

unread,
Dec 4, 2014, 5:18:24 AM12/4/14
to fltkg...@googlegroups.com
> Alternatively, just use any compiler, and edit the
> executable image with CFF Explorer
> (MajorSubsystemVersion is in the "Optional Header" section).


Does that work? Interesting...
I might give that a shot then, since I do not have the VS tools, but I do have Win7; be interesting to see if I can get a mingw build to exhibit the failure.

ekstrand...@gmail.com

unread,
Dec 5, 2014, 2:23:52 AM12/5/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Just to clarify, the x_, y_, w_ and h_ members of the Fl_Window do change here as well, so it's the same case as greentea's. Sorry if I mislead you, I just noticed that resizing explicitly didn't help, so I assumed that it didn't detect the resize. Anyway, I really appreciate your help and I'm looking forward to an adequate solution. I'm afraid I can't be of much help in the internals of FLTK but just let me know if I should test something!

greentea101

unread,
Dec 6, 2014, 8:39:13 PM12/6/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
I had free time today, and was able to come up with a quick (but functional) fix. I made changes to both Fl_X::make and Fl_X::fake_X_wm, and I changed how the former calls and uses the latter. The changes to fake_X_wm() are done in such a way that it can work in both the new way and the old (in case it's called from anywhere other than Fl_X::make - I haven't checked).

Essentially, I modified make() to give fake_X_wm the window styles for the window to be created, so that fake_X_wm can then use AdjustWindowRectEx instead of having to calculate things manually.

Changes to Fl_X::fake_X_wm:

int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by, DWORD style, DWORD exstyle) {
 
int W, H, xoff, yoff, dx, dy;
 
int ret = bx = by = bt = 0;

 
int fallback = 1;
 
if (!w->parent()) {
   
if (fl_xid(w) || style) {
     
// The block below calculates the window borders by requesting the
     
// required decorated window rectangle for a desired client rectangle.
     
// If any part of the function above fails, we will drop to a
     
// fallback to get the best guess which is always available.
     
     
if (!style) {
         HWND hwnd
= fl_xid(w);
         
// request the style flags of this window, as WIN32 sees them
         style
= GetWindowLong(hwnd, GWL_STYLE);
         exstyle
= GetWindowLong(hwnd, GWL_EXSTYLE);
     
}
...

Changes to Fl_X::make:

...
    styleEx
|= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; // changes start after this line

   
int wintype = 0;
   
if (w->border() && !w->parent()) {
     
if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) wintype = 2;
     
else wintype = 1;
   
}

   
switch (wintype) {
     
// No border (used for menus)
     
case 0:
        style
|= WS_POPUP;
        styleEx
|= WS_EX_TOOLWINDOW;
         
break;

     
// Thin border and title bar
     
case 1:
        style
|= WS_DLGFRAME | WS_CAPTION;
       
if (!w->modal())
          style
|= WS_SYSMENU | WS_MINIMIZEBOX;
       
break;

     
// Thick, resizable border and title bar, with maximize button
     
case 2:
        style
|= WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_CAPTION;
       
if (!w->modal())
          style
|= WS_MINIMIZEBOX;
       
break;
   
}

   
int xwm = xp , ywm = yp , bt, bx, by;
    fake_X_wm
(w, xwm, ywm, bt, bx, by, style, styleEx);
   
if (by+bt) { // changes stop at this line
...

You'll also have to change the declaration of fake_X_wm in win32.H:

  static int fake_X_wm(const Fl_Window* w,int &X, int &Y,
                         
int &bt,int &bx,int &by,DWORD style=0,DWORD styleEx=0);

As far as I can tell, the only problem with this approach, is that if AdjustWindowRectEx fails, then the fallback code is used anyway. I think it's very unlikely for that to happen though, so much so that I'm wondering if it's even worth trying to fix the fallback code anymore (my motivation to do that has dropped by like 80%). Why do you guys think about all this?

@Andreas


Sorry if I mislead you, I just noticed that resizing explicitly didn't help, so I assumed that it didn't detect the resize.

That's alright, no need to apologize. I had suspected that was the case, but wasn't sure.

I'm afraid I can't be of much help in the internals of FLTK but just let me know if I should test something!
 
Well, implement these changes and see if anything breaks on your end, I guess (and that also goes for anyone else interested).

greentea101

unread,
Dec 7, 2014, 9:26:16 AM12/7/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
I just realized that it may not be clear what to do with the code I posted, so I've attached an explanatory image, and a Diffutils patch file if you prefer that. I've never used Diffutils before, so I hope I didn't mess anything up.
Fl_win32.patch
copypaste_instructions.png

ekstrand...@gmail.com

unread,
Dec 9, 2014, 9:43:13 AM12/9/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Excellent instructions, greentea - thank you! I implemented your changes easily and it works great! I hope this will be committed to the repository as soon as possible, since I would want to run with at least a specified revision of the code.

Albrecht Schlosser

unread,
Dec 9, 2014, 10:45:51 AM12/9/14
to fltkg...@googlegroups.com
On 09.12.2014 15:43 ekstrand...@gmail.com wrote:

> Excellent instructions, greentea - thank you! I implemented your changes
> easily and it works great! I hope this will be committed to the
> repository as soon as possible, since I would want to run with at least
> a specified revision of the code.

Now that we appear to be near to a working resolution - maybe we are
already there - it would be helpful if you could file an STR with a
description of the issue (summary):

http://www.fltk.org/str.php

Please drop a note here (with the STR #) when done.

> On Sunday, December 7, 2014 3:26:16 PM UTC+1, greentea101 wrote:
>
@Greentea: Thanks very much for your work on this topic and the patch.
It would be very much appreciated by the devs if you could attach your
patch to the STR Andreas will hopefully file soon.

This makes sure that neither the issue nor the patch will be forgotten,
and we will have a short documentation of the issue when we commit the
changes.

Thanks to both of you in advance!

MacArthur, Ian (Selex ES, UK)

unread,
Dec 9, 2014, 10:55:51 AM12/9/14
to fltkg...@googlegroups.com
> @Greentea: Thanks very much for your work on this topic and the patch.
> It would be very much appreciated by the devs if you could attach your
> patch to the STR Andreas will hopefully file soon.

Does the function:

Fl_X::fake_X_wm(...)


have a user-visible scope?

If so, we may have a problem, as the patch will change its ABI which may not be a Good Thing...

So if Fl_X::fake_X_wm() is visible, we'll need to find another way to pass the relevant window style parameters around...

Of course, if Fl_X::fake_X_wm() is hidden internally to fltk, we are probably good to go.

Thoughts?

--
Ian

ekstrand...@gmail.com

unread,
Dec 9, 2014, 2:50:16 PM12/9/14
to fltkg...@googlegroups.com
Sure, just registered STR #3167.

ekstrand...@gmail.com

unread,
Dec 9, 2014, 2:56:12 PM12/9/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Good point, Ian. The fake_X_wm method is a public static method in the Fl_X class which is export-declared with the FL_EXPORT macro. I guess this means that it has a user-visible scope and that this would change the ABI then? If I'm not mistaken? Thoughts, greentea?
/Andreas

greentea101

unread,
Dec 9, 2014, 3:40:13 PM12/9/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
I don't think the user is supposed to ever call fake_X_wm, or even be aware of its existence, so I'm not sure I understand what the concern with the ABI is about. The class Fl_X is obviously for the internal use of the library, and is not even listed in the documentation. I don't have experience with libraries, so I guess I'm missing something?

Ian MacArthur

unread,
Dec 9, 2014, 5:40:41 PM12/9/14
to fltkg...@googlegroups.com
On Tue Dec 09 2014 20:40:13, 'greentea101' via fltk.general wrote:
> I don't think the user is supposed to ever call fake_X_wm, or even be aware of its existence,

Indeed; it doesn’t seem like the sort of thing that the user should have to deal with but...

> so I'm not sure I understand what the concern with the ABI is about. The class Fl_X is obviously for the internal use of the library, and is not even listed in the documentation. I don't have experience with libraries, so I guess I'm missing something?


The class Fl_X is marked FL_EXPORT, so presumably is visible in the lib and in the shared objects; within that class fake_X_wm() is in the public part of the object...

So, whether we intend the user to access the method or not, it does look like it might currently be in a user-visible scope, so presumably does alter the ABI if we change it.

Others (like Lauri for example) probably have a better idea of how this effects ABI, and whether we care in this case (though I doubt Lauri’s that bothered about Win32 compatibility though ;-)...

Thoughts, anyone...?



A.J. bonnema

unread,
Dec 9, 2014, 6:22:27 PM12/9/14
to fltkg...@googlegroups.com
On 09-12-14 23:40, Ian MacArthur wrote:
> The class Fl_X is marked FL_EXPORT, so presumably is visible in the
> lib and in the shared objects; within that class fake_X_wm() is in the
> public part of the object... So, whether we intend the user to access
> the method or not, it does look like it might currently be in a
> user-visible scope, so presumably does alter the ABI if we change it.
> Others (like Lauri for example) probably have a better idea of how
> this effects ABI, and whether we care in this case (though I doubt
> Lauri’s that bothered about Win32 compatibility though ;-)...
> Thoughts, anyone...?
Why don't you turn off the FL_EXPORT and see if anyone responds? And if
someone does, you could provide a replacement provided there is
legitimate use for it. Otherwise, having it as FL_EXPORT is just a bug
.... that needs squashing .... true?

Kind regards, Guus.

Greg Ercolano

unread,
Dec 9, 2014, 6:30:00 PM12/9/14
to fltkg...@googlegroups.com
On 12/09/14 14:40, Ian MacArthur wrote:
> Others (like Lauri for example) probably have a better idea of how this effects ABI,
> and whether we care in this case (though I doubt Lauri’s that bothered about Win32 compatibility though ;-)...
>
> Thoughts, anyone...?

Can't hurt to make it an ABI feature for 1.3.x,
and then clean it up in 1.4.0. That way there'd be no problem.

John Gal

unread,
Dec 9, 2014, 11:53:44 PM12/9/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
I'm a beginning amateur user and am trying to update and modify an existing C++ program where the user interface was created with FLTK 1.1.3. My problem is very much the same i.e. window size decreases each time it's called. I'm using VS2012 and Win 7. The problem did not exist on Windows XP.. Is there a simple way of rectifying this problem since my knowledge of FLTK is very limited?


On Wednesday, November 26, 2014 3:40:02 AM UTC+11, MacArthur, Ian (Selex ES, UK) wrote:

> I'm building my application on a new Windows development machine with
> Windows 8.1 (instead of previous Windows 7) and VS2013 (instead of
> previous VS2008) but with the same fltk-1.3.0 source as before.

You need to upgrade to 1.3.3, or the recent weekly snapshots.

Or switch to using mingw, or an older version of VC.

Or, use a bin editor to set the executable type to something older than Win7...


Basically, newer versions of the VS tools, running the exe on Win7 and later, will do some rather odd things to the window border settings.

I think this is fixed (or worked around at any rate) for fltk-1.3.3, but 1.3.0 is pretty old now and it has no idea what Win7, Win8.x or VS2013 are...

Greg Ercolano

unread,
Dec 10, 2014, 12:23:52 AM12/10/14
to fltkg...@googlegroups.com
On 12/09/14 07:45, Albrecht Schlosser wrote:
>> On Sunday, December 7, 2014 3:26:16 PM UTC+1, greentea101 wrote:
>> I just realized that it may not be clear what to do with the code I
>> posted, so I've attached an explanatory image, and a Diffutils patch
>> file if you prefer that. I've never used Diffutils before, so I hope
>> I didn't mess anything up.
>
> @Greentea: Thanks very much for your work on this topic and the patch.
> It would be very much appreciated by the devs if you could attach your
> patch to the STR Andreas will hopefully file soon.

Please note Andreas created STR#3167, so you can now add any patches
to that str (via 'Post File') and keep up with the bug's progress:
http://www.fltk.org/str.php?L3167

Greg Ercolano

unread,
Dec 10, 2014, 12:34:12 AM12/10/14
to fltkg...@googlegroups.com
On 12/09/14 20:53, John Gal wrote:
> I'm a beginning amateur user and am trying to update and modify
> an existing C++ program where the user interface was created
> with FLTK 1.1.3. My problem is very much the same i.e. window size
> decreases each time it's called. I'm using VS2012 and Win 7.
> The problem did not exist on Windows XP.. Is there a simple way
> of rectifying this problem since my knowledge of FLTK is very limited?

A bug has been opened for this here:
http://www.fltk.org/str.php?L3167

You can either poll that page manually to see progress, or add yourself
to the bug so as to receive email notifications on its progress.

A patch has been proposed by greentea101 on fltk.general before the
above bug was opened, and it will probably be added to the bug in the
near future.

Meanwhile, you can see the proposed patch here:
https://groups.google.com/d/msg/fltkgeneral/_QUBkFsbQnQ/Ejp7-gHIstUJ


MacArthur, Ian (Selex ES, UK)

unread,
Dec 10, 2014, 4:28:17 AM12/10/14
to fltkg...@googlegroups.com

> Why don't you turn off the FL_EXPORT and see if anyone responds?

Because we are not MS, and do not test by dropping "known-broken" code on our users?


> And if
> someone does, you could provide a replacement provided there is
> legitimate use for it. Otherwise, having it as FL_EXPORT is just a bug
> .... that needs squashing .... true?

The main problem is likely to be if folks are using the DLL's. Then the breakage will occur when they pull a shared object that has the "fix" applied and their code crashes...

But the change is not in their code, but in a system resource, in effect, so they will have a hard time debugging that... I'm not keen, if there is any chance we can work around this in some other way.

MacArthur, Ian (Selex ES, UK)

unread,
Dec 10, 2014, 4:30:15 AM12/10/14
to fltkg...@googlegroups.com
> > Thoughts, anyone...?
>
> Can't hurt to make it an ABI feature for 1.3.x,
> and then clean it up in 1.4.0. That way there'd be no problem.

Yes, but we probably need a short term fix right now, too, as this will hit more folks as the newer VS tools roll out and Win8 gains traction.

And I'm guessing a fair few of those hit will not be the ones who are best able to work with alternate build options...

MacArthur, Ian (Selex ES, UK)

unread,
Dec 10, 2014, 4:36:34 AM12/10/14
to fltkg...@googlegroups.com

> I'm a beginning amateur user and am trying to update and modify an
> existing C++ program where the user interface was created with FLTK
> 1.1.3. My problem is very much the same i.e. window size decreases each
> time it's called. I'm using VS2012 and Win 7. The problem did not exist
> on Windows XP.. Is there a simple way of rectifying this problem since
> my knowledge of FLTK is very limited?


There are a couple of things you can do to work around this in the short term:

1: Apply greentea's patch (though I acknowledge that may be a step to far right now!)

-or-

2: See the workaround in STR 3061

http://www.fltk.org/str.php?L3061

Basically, if you build your code with the system version set to XP, you get the "legacy" behaviour like on XP and "all is well".

I quote greentea's note from that STR;

"In Visual C++ 2012, the subsystem version is controlled by
the setting

"Configuration Properties->General->Platform Toolset"
from the project settings.
Alternatively, it can also be changed from

"Linker->System->Minimum Required Version"."


Try this, let us know what happens.

--
Ian

A.J. bonnema

unread,
Dec 10, 2014, 5:32:20 AM12/10/14
to fltkg...@googlegroups.com
On 10-12-14 10:28, MacArthur, Ian (Selex ES, UK) wrote:
>> Why don't you turn off the FL_EXPORT and see if anyone responds?
> Because we are not MS, and do not test by dropping "known-broken" code on our users?
>
>
>> And if
>> someone does, you could provide a replacement provided there is
>> legitimate use for it. Otherwise, having it as FL_EXPORT is just a bug
>> .... that needs squashing .... true?
> The main problem is likely to be if folks are using the DLL's. Then the breakage will occur when they pull a shared object that has the "fix" applied and their code crashes...
>
> But the change is not in their code, but in a system resource, in effect, so they will have a hard time debugging that... I'm not keen, if there is any chance we can work around this in some other way.
I knew I was in over my head when I responded, but it seemed such a
logical thing to do. Of course if the result is very hard to debug it
might not be such a good idea. Plz forget about it. Still, to me (as a
new user) it sounds weird that I could call a method that should not be
visible to me at all.

Would their be an alternative like having the application abort in an
obvious and clean way if someone calls the offensive method? That way it
could even point toward the bug and/or the fix. Just trying to help even
if new to the game.

Kind regards, Guus.

manol...@gmail.com

unread,
Dec 10, 2014, 7:13:05 AM12/10/14
to fltkg...@googlegroups.com, ian.ma...@selex-es.com


On Tuesday, 9 December 2014 16:55:51 UTC+1, MacArthur, Ian (Selex ES, UK) wrote:
> @Greentea: Thanks very much for your work on this topic and the patch.
> It would be very much appreciated by the devs if you could attach your
> patch to the STR Andreas will hopefully file soon.

Does the function:

    Fl_X::fake_X_wm(...)


have a user-visible scope?

If so, we may have a problem, as the patch will change its ABI which may not be a Good Thing...

So if Fl_X::fake_X_wm() is visible, we'll need to find another way to pass the relevant window style parameters around...

Of course, if Fl_X::fake_X_wm() is hidden internally to fltk, we are probably good to go.

 Fl_X::fake_X_wm() is indeed exported and callable by user code, even if the doc clearly recommends
not to do so (http://www.fltk.org/doc-1.3/osissues.html).

But this function is used only within Fl_win32.cxx, so it can be rewritten, say,
static int fake_X_wm_Win7_compat(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by, ........)
with the new arguments it needs. The new function can be called by Fl_X::make() and other
functions of Fl_win32.cxx that use it.
The exported
int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
can be left as is, or changed to call the new function, so the ABI is preserved.


Albrecht Schlosser

unread,
Dec 10, 2014, 9:02:08 AM12/10/14
to fltkg...@googlegroups.com
Yes, that's what I thought, too. Unfortunately the method accesses some
private members of Fl_Window, so this is not as easy as it seems to be.
I just tried it as a proof of concept and got compile errors (stripped
to be not too long here):

Compiling Fl.cxx...
../FL/Fl_Window.H:115:9: error: 'uchar Fl_Window::size_range_set' is private
uchar size_range_set;
^
../FL/Fl_Window.H:113:19: error: 'int Fl_Window::maxw' is private
int minw, minh, maxw, maxh;
^
../FL/Fl_Window.H:113:7: error: 'int Fl_Window::minw' is private
int minw, minh, maxw, maxh;
^
../FL/Fl_Window.H:113:25: error: 'int Fl_Window::maxh' is private
int minw, minh, maxw, maxh;
^
../FL/Fl_Window.H:113:13: error: 'int Fl_Window::minh' is private
int minw, minh, maxw, maxh;
^

Another note: fake_X_wm is also defined for Mac (in FL/mac.H) and used
in Fl_cocoa.mm as well.

I believe that we can resolve this though (but I didn't check the details).

I updated the STR with some observations and thoughts.

greentea101

unread,
Dec 10, 2014, 12:02:11 PM12/10/14
to fltkg...@googlegroups.com

Yes, that's what I thought, too. Unfortunately the method accesses some
private members of Fl_Window, so this is not as easy as it seems to be.
I just tried it as a proof of concept and got compile errors

 Then why not make the new function a friend of Fl_Window?

class FL_EXPORT Fl_Window : public Fl_Group {

 
friend int fake_X_wm_Win7_compat(const Fl_Window* w,int &X, int &Y,
                         
int &bt,int &bx,int &by,ulong style,ulong styleEx);
...
};

I had to use "ulong" because "DWORD" wasn't defined, not sure what's going on there. But other than that, I replaced all calls to Fl_X::fake_X_wm with calls to fake_X_wm_Win7_compat, and everything compiled and ran fine.

Albrecht Schlosser

unread,
Dec 10, 2014, 12:17:32 PM12/10/14
to fltkg...@googlegroups.com
On 10.12.2014 18:02 'greentea101' via fltk.general wrote:
>
> /Yes, that's what I thought, too. Unfortunately the method accesses
> some
> private members of Fl_Window, so this is not as easy as it seems to be.
> I just tried it as a proof of concept and got compile errors /
>
>
> Then why not make the new function a friend of Fl_Window?
>
> |
> classFL_EXPORT Fl_Window:publicFl_Group{
>
> friendintfake_X_wm_Win7_compat(constFl_Window*w,int&X,int&Y,
> int&bt,int&bx,int&by,ulongstyle,ulongstyleEx);
> ...
> };
> |
>
> I had to use "ulong" because "DWORD" wasn't defined, not sure what's
> going on there. But other than that, I replaced all calls to
> Fl_X::fake_X_wm with calls to fake_X_wm_Win7_compat, and everything
> compiled and ran fine.

Yep, that would work, thanks for the hint. However I'm not keen on
adding friend functions.

I didn't check further, but there are probably public member functions
available for some or all of the member variables the function accesses.

I'd prefer to use this instead of new 'friend' functions.

Ian MacArthur

unread,
Dec 10, 2014, 12:46:36 PM12/10/14
to fltkg...@googlegroups.com
I’m not keen on the friend option; would it not be OK to just make fake_X_wm_Win7_compat() a private method?

Then it would be OK to call from within Fl_win32.cxx, would have access to the private members, and would not be callable by end users...

And we would (for now) retain the current “public” fake_X_wm method to preserve the ABI, just in case anyone does actually use it, but have it call the new fake_X_wm_Win7_compat method internally (with suitable guesses for the extra parameters)...?


Presumably the same pattern can be followed in the OSX fake_X_wm method, if such change is ever needed?






greentea101

unread,
Dec 10, 2014, 4:27:22 PM12/10/14
to fltkg...@googlegroups.com
 
I’m not keen on the friend option; would it not be OK to just make fake_X_wm_Win7_compat() a private method?
 
That would work, but you'd have to make the Fl_Window class a friend of Fl_X, because a bunch of its member functions call fake_X_wm().

greentea101

unread,
Dec 10, 2014, 4:32:39 PM12/10/14
to fltkg...@googlegroups.com

because a bunch of its member functions call fake_X_wm().

DUH! I need to take a break from this. Sorry for the spam.

ekstrand...@gmail.com

unread,
Dec 16, 2014, 2:40:16 AM12/16/14
to fltkg...@googlegroups.com
What's the status for this right now? In the meantime I'm using greentea's fix locally here, but it would be great if a working solution was in place soon, so we can base our software release in January on at least a specified revision.

imm

unread,
Dec 16, 2014, 5:02:53 AM12/16/14
to general fltk
ekstrand.andreas wrote:

What's the status for this right now? In the meantime I'm using greentea's fix locally here, but it would be great if a working solution was in place soon, so we can base our software release in January on at least a specified revision.

++++

The current patch looks to be ABI breaking, so probably can't be deployed in its current form...

Though that does not stop you using it if you are static linking, of course.

Or you can make sure the subsystem version code is set to 5 or less, of course, on the generated exe.

What you'd ideally want is a released version of fltk with a non ABI breaking fix in place. I'm not confident that will be in place in the timescale you have outlined...
--
Ian

Sent, much to my surprise, from my Fairphone FP1

Greg Ercolano

unread,
Dec 16, 2014, 5:31:11 PM12/16/14
to fltkg...@googlegroups.com
On 12/15/14 23:40, ekstrand...@gmail.com wrote:
> What's the status for this right now?

I believe the open bug to track is this one:
http://www.fltk.org/str.php?L3167


Reply all
Reply to author
Forward
0 new messages