Extend FLTK with a cross-platform way to undock and dock widget groups #1257
Replies: 7 comments 9 replies
|
Hey! Currently I only have access to a X desktop, so I tested on that. Everything seems to be in order. If I understand correctly, you're aiming for something slightly different than is achieved using my or Gonzalo's implementation (still, they vary a great deal). I've got a couple of questions:
As for your question, I don't think it can be answered yes/no because there is a lot of ways to define the problem of docking. For one, my docking is so different that it either wouldn't work as replacement for the other even with major modifications. |
|
I tried it. Its API is really clean, but man, you have your work cut out for you if you want to make it generic! Here are my comments:
|
|
@ManoloFLTK Thanks for this proposal. I didn't have much time to test, but my basic feeling is that it's a nice and useful feature. I ran your test program and it was a positive experience, but it also revealed (to me at least) something similar to @ggarra13's arguments. In short: I'd wish more flexibility, but this is only a first impression. Please don't get me wrong, I think it's a great start. I'm writing this some days after my tests, w/o actually looking at the code, which isn't that important for getting a feeling about the issue. Let's start with the group that is to be dragged and docked elsewhere. I understand that it needs a kind of handle to be dragged around, that's fine. The only thing I don't understand is its name in the implementation: why is it called "command" box? It could be The more important part is the receiving group. The documentation says: when a draggable group is dragged to a target box "it takes the size of its receiving 'target box'". This seems to be too restrictive, particularly because the receiving group has to reserve space for the draggable box - which is IMHO counter-intuitive. I imagine that any Fl_Group could be a receiving group, for instance an Fl_Flex or Fl_Grid (if enabled by calling a specific method and adding a target box). Fl_Flex would be much simpler, so let's think about this kind of group first. The
An Sorry for being so vague, I'm just thinking about the problem of dragging groups and inserting them anywhere in an existing GUI. The main new feature would be that a receiving group would resize its existing and the new widget itself w/o having to keep a reserved space. I don't have a real proposal how to implement this, it's just from the view of a "user". I hope this helps anyway. |
|
After some more thought, I'll add another of my two cents. I agree with two points brought up:
To elaborate on point 2, I think a good way to go is to provide only the fundamentals for docking in Moreover, I think the concept of "target box" is not very useful. In my opinion, a better solution is to add a few events that can be handled by a subclass of
So, instead of rigidly defined "target box", the subclass would handle the positioning of the dock group. This would be trivial for a Also, by doing this with events as I suggest, building on the FLTK docking would be much easier. Docking becomes a extensible "first class citizen", not a extension.
|
|
Proposal to add support of docking/undocking in FLTK with a new widget Fl_Dockable_Group - version 2 Get, build, and run the complete proposal with: Extending FLTK with support of docking/undocking is especially important for its Wayland backend because Wayland prohibits the implementation of a docking mechanism without extending FLTK. The reason is that, under Wayland, a window is not aware of its location within the display, and even less of its location relatively to that of other windows, a key information for the docking operation. Wayland has been recently extended with a new protocol "
That's exactly undocking/docking support. Therefore, docking requires the Wayland backend of FLTK to be extended to support this new protocol. Furthermore, Wayland implements docking as a variation of the drag-and-drop mechanism, which is very different from how other platforms see a docking operation. A new FLTK class provides the opportunity to completely hide the differences between how docking works under the various platforms. The new Fl_Dockable_Group class derives from Fl_Group and as such can contain any widget collection. Two notions embody the functioning of this class.
FLTK defines only a very basic "docking target widget", class A "drag widget" and its parent Fl_Dockable_Group alternate between 3 states during their lifetime
FLTK changes the label and the background color of the "drag widget" when its state changes using values that can be freely set by the FLTK app. A "docking target widget" can be in two states: 1) the target would dock a dockable that is presently above it if the mouse would be released; 2) something else. Five elementary operations that may be performed by a "docking target widget" have been identified. The recipe to define a new "docking target widget" class requires that this class defines 2 to 5 static functions that perform some or all of these elementary operations according to what is expected from the class:
These operations are believed to contain all ways by which possible docking targets may differ. FLTK performs all the mechanics of receiving events, transmitting them from containers to widgets, working differently under Wayland than under other platforms, and calling each elementary operation when appropriate. Following a very clever suggestion by @CyprinusCarpio, FLTK uses internally 5 newly defined docking-related events: FL_DOCK_ENTER, FL_DOCK_DRAG, FL_DOCK_RELEASE, FL_DOCK_LEAVE and FL_UNDOCK. The docking operation creates a situation that is new in FLTK where a single event, a mouse button drag or release, is of direct interest to two widgets from two windows: the active dockable and the target widget below it. Therefore, the new events, say FL_DOCK_RELEASE, are sent internally by FLTK to docking target widgets, and also to the dockable which can receive them via its handle(int) method and act accordingly. Furthermore, only under the Wayland platform, the docking/undocking mechanism is implemented as a modified drag-and-drop and generates FL_DND_ENTER, FL_DND_DRAG, … events. These are transformed internally by FLTK into FL_DOCK_ENTER, FL_DOCK_DRAG, … events to become platform-independent FLTK events sent to Fl_Widget's as usual. There are 2 quite distinct implementations behind class Fl_Dockable_Group. This explains the need of class Fl_Dockable_Group_Driver, internal to FLTK. One is for all platforms where the position of a window in a display can be programmatically set and read (macOS, X11, Windows). Any future FLTK platform with this property would not need special development for class Fl_Dockable_Group. The second is Wayland-specific. The new class requires a few changes to the FLTK core:
Program
|
|
I have a question. If you want to have a Fl_Dockable_Group that allows docking multiple "drag widgets" and packing them? How would you go about it? Can you derive from both Fl_Dockable_Group and Fl_Flex for example? Or would you derive from Fl_Dockable_Group and have to re-code most of Fl_Flex again? |
|
@ManoloFLTK Got it now. I looked at the code. The handle_docking_target function REALLY needs proper documentation as it allows you to do a lot of things. |

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
See version 2 of this proposal in comment below dated December 4, 2025
This discussion proposes to extend FLTK with a cross-platform way to undock and dock widget groups.
The proposed, fully documented, implementation is available at branch
dock-undockof my FLTK fork.Docking widget groups in a Wayland client application poses a difficult problem because Wayland completely hides the position of a window in a display which prevents the detection of whether a window is moved above a given part of the application's GUI. Two major Wayland compositors, Gnome's Mutter and KDE's Kwin, have recently decided to implement a new Wayland protocol,
XDG toplevel drag, designed specifically to support widget docking. This proposed implementation solves the docking problem under Wayland using this new protocol, and has a backup mechanism based on Wayland's drag-and-drop feature to approximate widget docking in absence of theXDG toplevel dragprotocol.The present proposal extends FLTK with class
Fl_Dockable_Group, derived fromFl_Group, and defined as: a group that can be detached from its parent, dragged with the mouse to some destination, and docked there.Like any
Fl_Group, anFl_Dockable_Groupcan contain any set ofFl_Widget's. AnFl_Dockable_Groupobject becomes detachable and draggable to some destination after member functioncommand_box(int x, int y, int w, int h)is called once. This adds anFl_Boxto theFl_Dockable_Groupthat can be called its 'command box'. Class functionFl_Dockable_Group::target_box(int x, int y, int w, int h, Fl_Group *g)allows to define 'target boxes', that is, destination boxes to whichFl_Dockable_Groupobjects can be dragged and docked. That function is to be called once for each location in the GUI whereFl_Dockable_Groupobjects are susceptible to be docked.Once each
Fl_Dockable_Groupobject contains its 'command box' and a few 'target boxes' have been put in the GUI, anyFl_Dockable_Groupcan be moved to any 'target box' pressing the mouse on the group's 'command box', dragging the group away towards the chosen 'target box' and releasing the mouse.Class
Fl_Dockable_Groupis implemented for all FLTK platforms, Wayland included. While anFl_Dockable_Groupis being dragged away and before it docks somewhere, the group remains a functional, event-responding GUI element (under Wayland, this requires theXDG toplevel dragprotocol).A test program,
dock_undock, is added to provide usage examples. Commandmake dock_undockafter cmake configuration and generation of the FLTK fork will build this program.
@ggarra13, @CyprinusCarpio Would you agree to test class
Fl_Dockable_Groupand report here whether its 2 major components, the 'command box' and 'target boxes' render this class usable and adequate for FLTK client applications that use docking and undocking?Implementation details:
Fl_Dockable_Groupdragging and docking is performed via a Drag-and-Drop operation which itself can be implemented in 2 ways.XDG toplevel dragthat allows to detach theFl_Dockable_Group, transform it into a draggable window, and drop it to a 'target box' back into the form of anFl_Dockable_Group. The KWin compositor's support ofXDG toplevel dragforbids anFl_Dockable_Groupto be part of a subwindow.Fl_Dockable_Groupand uses it as the cursor image of a DnD operation that ends being dropped to a 'target box' or being cancelled.Fl_Dockable_Groupdragging and docking begins by transforming the group into a borderlessFl_Windowwhich can be dragged around with the mouse and docked to any 'target box', or sent back to its initial location with Escape.All reactions