FLTK logo

STR #2948

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 Home  |  Articles & FAQs  |  Bugs & Features  |  Documentation  |  Download  |  Screenshots  ]
 

Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]

STR #2948

Application:FLTK Library
Status:1 - Closed w/Resolution
Priority:1 - Request for Enhancement, e.g. asking for a feature
Scope:3 - Applies to all machines and operating systems
Subsystem:Core Library
Summary:Add a method to Fl_Widget that returns its top-level window
Version:1.3-feature
Created By:greg.ercolano
Assigned To:greg.ercolano
Fix Version:1.3-current (SVN: v9876)
Fix Commit:5fda885c0306561ab53266e16d87b3c4e164572c
Update Notification:

Receive EMails Don't Receive EMails

Trouble Report Files:


Name/Time/Date Filename/Size  
 
#1 greg.ercolano
12:05 Apr 09, 2013
top_window.patch
2k
 
 
#2 greg.ercolano
12:09 Apr 09, 2013
test-top_window.cxx
2k
 
 
#3 manolo
03:42 Apr 11, 2013
window.patch
1k
 
     

Trouble Report Comments:


Name/Time/Date Text  
 
#1 greg.ercolano
12:05 Apr 09, 2013
This STR spawned from a discussion on fltk.development,
Subject: "RFC: method to find top level window?"

The suggestion is to add a method that returns the top-level window
for the current widget, i.e. the 'window manager window' the widget
is in.

This differs from Fl_Widget::window() which may return a sub-window,
if there is one, not necessarily the top-level window.

I suggested "toplevel_window()" because the term 'top-level' seems
to be used in the code comments, Albrecht offered "top_window()"
as a shorter alternative, which I think I'll go with here.

Attaching a patch suggesting the code implementation,
"toplevel_window.patch".

Also attaching a test program, "test-top_window.cxx"
which compares the return value of window() and top_window() for
various widgets and windows in the presence of sub-windows.

We should also probably do a code check on all of FLTK
to make sure "window()" isn't being used where top_window()
would be correct. I believe it's only recently that FLTK reliably
supported sub-windows, so the chances of apps using them are
higher now, and little problems are more likely to spring up,
such as STR #2944 [2].

Comments welcome.
 
 
#2 manolo
03:45 Apr 10, 2013
- The last statement of the Fl_Widget::top_window() function
may be written more simply:
   return w->as_window();

- I'm unsure this function would be useful. Can the knowledge of
the top enclosing window of an object be useful without knowledge of
the object coordinates relatively to this window?
May be what is needed would be along this line:
Fl_Window* Fl_Widget::top_window_offset(int& xoff, int& yoff)
 
 
#3 greg.ercolano
08:35 Apr 10, 2013
> Can the knowledge of the top enclosing window of an object
> be useful without knowledge of the object coordinates
> relatively to this window?

Simple case would be a widget (say a button) that wants to hide
the window its in. If the button is in a subwindow, window() wouldn't
work, bot top_window() would.

> May be what is needed would be along this line:
> Fl_Window* Fl_Widget::top_window_offset(int& xoff, int& yoff)

Actually just added such a thing in r9866 a few days ago to solve
STR#2944, but called it window_offset(). Perhaps I should add "top_"
to it though.. its not too late.
 
 
#4 AlbrechtS
11:38 Apr 10, 2013
Patch looks good, except what Manolo wrote already. We should remove this old and error-prone "w->type() >= FL_WINDOW" from the entire lib in favor of as_window().

WRT window_offset() vs. top_window_offset(): I strongly vote for the latter and consistent naming, i.e. top_window() and top_window_offset().

+1 for the patch with mods as written.
 
 
#5 greg.ercolano
13:00 Apr 10, 2013
> as_window()

    Yes, that looks good.. I'll do some tests; want to make sure
    it inherits through all the window options we have (Fl_Gl_Window, etc)

> window_offset() vs. top_window_offset(): I strongly vote for
> the latter and consistent naming

    Agreed.

    Will make changes and implement.

> We should remove this old and error-prone "w->type() >= FL_WINDOW"
> from the entire lib in favor of as_window().

    OK, I'll try to handle that too, but as a separate commit.
 
 
#6 greg.ercolano
13:39 Apr 10, 2013
Oh, BTW, I think I missed what Manolo might have been getting at
wrt the 'top_window_offset()' method.

So where we're at now, just to disambiguate:

    o There's currently a method Fl_Window::top_window_offset()
      (just renamed it from window_offset() in r9870)

    o We're proposing in this STR a new Fl_Widget::top_window().

I can see where the existing top_window_offset() should really
be a method of Fl_Widget, not just Fl_Window.. so that even
non-windows can find their offset relative to the top window
to be more useful.

So will look into changing that as well.
 
 
#7 greg.ercolano
14:16 Apr 10, 2013
OK:
   r9871: top_window(): implemented (using as_window())

   r9872: top_window_offset() now a member of Fl_Widget (was Fl_Window)
          and moved it near top_window() and window().
 
 
#8 greg.ercolano
14:22 Apr 10, 2013
..and finally:

  r9873: CHANGES file updated.

Comments before close?
 
 
#9 AlbrechtS
14:27 Apr 10, 2013
Comments? Yes: Great, thanks.

BTW: good catch that top_window_offset() should be a Fl_Widget method. I didn't realize that it was Fl_Window:: before.
 
 
#10 manolo
03:41 Apr 11, 2013
Thanks Greg for implementing exactly what I was getting at.

I still have a few remarks about the current implementation of:
Fl_Window* Fl_Widget::top_window_offset(int&, int&)

- The doc should say 'current widget' instead of 'current window'
because a widget is now current.

- I feel the widget-to-window cast
const Fl_Window *win = (const Fl_Window *)this;
is frightening, because widgets are not windows, in general.
It works here because only member functions from the parent Fl_Widget
class are employed. Rewriting it
Fl_Widget *win = (Fl_Widget*)this;
does just the same, removing the fear.

- This implementation applied to a window-less widget returns
this widget cast as a window, a potentially dangerous thing.
My suggestion would be to use (again) our friend Fl_Widget::as_window().

The attached window.patch gathers all of this.
 
 
#11 greg.ercolano
10:59 Apr 11, 2013
@manolo: Great -- agree with all, except perhaps loosing const here:

-  const Fl_Window *win = (const Fl_Window*)this;
+  Fl_Widget *win = (Fl_Widget*)this;

I think we can maintain const protection on the variable this way:

    const Fl_Widget *win = this;
    :
    return ((Fl_Widget*)win)->as_window();

..this ensures const protection for all uses of win within the code,
and we only turn it off when we need to (eg. the non-const as_window() call)

Also, I should probably change all instances of 'win' -> 'w' in the
code, since it's really working with widgets now.

Thanks for the peer review -- will hold on comments regarding const
above, as am curious if there's a reason not to.
 
 
#12 AlbrechtS
02:45 Apr 12, 2013
+1 for renaming to w instead of win (or maybe widget to avoid name clashes with w(), but that's not important here, IMO)

+0 for maintaining constness (yes, I mean + zero). constness doesn't gain much here, and since compilers become pickier more and more, there is the danger of getting a warning when it's cast away for as_window(), as Ian wrote elsewhere. If not now, then maybe later. We're only calling const methods anyway, as x(), y(), window(), and this code is not subject to be changed in the future. Using const here would IMHO only protect ourselves from adding code that would modify the widget in question, and as said before, we won't add more code. Just my 2 (€)ct.
 
 
#13 manolo
03:41 Apr 12, 2013
@Greg: Yes to all proposed changes.
There's no reason, but laziness, to loose const protection.
 
 
#14 greg.ercolano
09:57 Apr 12, 2013
Albrecht> We're only calling const methods anyway, as x(), y(), window(),
Albrecht> and this code is not subject to be changed in the future.

Yes, though for some reason "as_window()" is not const,
(it probably should be), which is why that cheat is necessary at the end there. Maybe using const_cast<Fl_Widget*>(w)->as_window() is better,
which is what I decided to go with in top_window_offset().. will check.

Note in manolo's implementation, const is cast away at the top
at the declaration of the variable, but I just switched it to const
and cast const away only at the place where it was needed, at the
as_window() call.

So this does two things:

   1) Keeps the variable const so one can't later add code like
      w->label("yoo hoo"); without getting an error..
      hey, it could be more subtle ;)

   2) Highlights exactly where the cheat is needed (at as_window())
      so if as_window() ever changes in the future to be const, it's
      easier to find and remove the const cast-away.

Is there a reason as_window() and friends (other virtual
implementations) are not const methods? Fl_Window::window() is.
 
 
#15 greg.ercolano
16:11 Apr 12, 2013
Updated fixes in r9875 and r9876.

About to close, unless there's more to add.

Regarding const mods to at_window() and friends,
let's continue that on fltk.dev and make a separate STR for that.
 
 
#16 greg.ercolano
16:15 Apr 12, 2013
Oh, I should add..
all mods to date (r9876, including static_cast<>) build OK on:
redhat9, irix6.5, centos 5.6, Mountain Lion default compiler (picky),
Sci Linux 6 (very picky, latest linux I have) gcc 4.4.6, and VS 2010.
 
 
#17 greg.ercolano
16:21 Apr 12, 2013
Sorry, as Ian points out on fltk.dev, meant to say const_cast<>
in the above, not static_cast<>.
 
 
#18 greg.ercolano
12:10 Oct 27, 2014
Fixed in Subversion repository.  
 
#19 AlbrechtS
19:05 Jan 15, 2023
Add git commit info: 5fda885c0306561ab53266e16d87b3c4e164572c for svn r9876.  
     

Return to Bugs & Features ]

 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.