Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-12

Docking state question

4 messages · 1 person · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Hans-Peter Diettrich

Since two weeks I'm offline, here some questions and comments about docking, in general and on Win7/64 in detail (in case it matters). I've installed Lazarus 0.9.28.2 32 and 64 bit, and SVN trunk. Unfortunately I cannot separate all issues properly, with my current mix of Lazarus and FPC and 32/64 bit versions :-(

In 0.29.2-32 (downloaded yesterday) I found docking support lacking or inacceptable. The DockManager examples are crippled, no dockable IDE, and the DockRect flickers heavily while dragging (refresh only twice per second, using examples\dockmanager\easytree). Are these known issues?

In the 64 bit and SVN trunk version (32 bit) docking works much smoother, but the dockable IDE is a mess. The DragManager gets no keys, i.e. docking cannot be aborted with Esc. The dockable IDE is not dockable at all, i.e. the docked forms cannot be undocked or docked to other windows. Perhaps this is due to the same problem, with message forwarding to the DragManager?

IDE window positions don't work for me on a second monitor, above the primary monitor. Whenever the IDE or a project is reopened, all windows are moved to the primary monitor. No such problems occur with the dockmanager\ide_demo2, i.e. it's an IDE problem. That's why I tried to use a dockable IDE, where the DockMaster could control window positions better, but failed with above problems.

Now I'd like to learn more about the intended future support of docking in general, and with the IDE in detail. When I'm online again (next year?) I can continue to contribute to these topics more directly. In the meantime I hope that the two IDE show stoppers can be cured by the team:

- pass key up/down messages (and more) to the DragManager
- retain IDE window positions with multiple monitors

In my current (private) work I've tested a new DragManager version, that routes all drag messages through the DockManager (if installed in the target site), and with the Performer functionality moved into the drag/dock objects. No problems found with this (fully optional) change.

In another experiment I tried to separate the DockManager functionality into dragging (site specific) functionality (elastic sites, KeepDockSiteSize), and into layout management (docktree, anchor docking, child sizing...). Wouldn't it be nice to add docking capabilities to all kinds of containers (panels, toolbars, source editor tabs...), without reimplementing the dragging part over and over again? The Controls[] and DockClients[] lists can be combined (i.e. DockClients[] removed), and a variety of layout managers can be used independently from docking support. Herefore only a layout API (child sizing and placement) is required, that allows to integrate various layout managers into the general (autosize...) methods.

In a first approach I derived the layout functionality of the DockManager from TChildSizing, so that TWinControl.ChildSizing can become a reference to any installed layout manager. What remains to do is the specification of a more general API in TChildSizing, that allows for other management of child controls (tree, anchored...). Then the still existing DockManager property could handle all the docking aspects, like extending/shrinking docksites or glueing them together, while it can defer the precise layout of the site to the ChildSizing manager. Delphi compatibility is not broken, it only is extended by separately installable layout managers.

Any comments?

DoDi

Reply by email

Hans-Peter Diettrich
to Hans-Peter Diettrich
Show quoted text 5 lines
In the 64 bit and SVN trunk version (32 bit) docking works much smoother, but the dockable IDE is a mess. The DragManager gets no keys, i.e. docking cannot be aborted with Esc. The dockable IDE is not dockable at all, i.e. the docked forms cannot be undocked or docked to other windows.

The same applies on Linux :-(

DoDi

Reply by email

Hans-Peter Diettrich
to Hans-Peter Diettrich
> The DragManager gets no > keys, i.e. docking cannot be aborted with Esc.

Found the bug near rev. 26309/12: the new DockWindow in win32lclintf.inc does not send key messages to the DragManager. Here a workaround:

function DockWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
     LParam: Windows.LParam): LResult; stdcall;
var
   CharCode: word;
   ss: TShiftState;
begin
   case Msg of
   WM_KEYDOWN:
     if DragManager.IsDragging then begin
       CharCode := word(WParam);
       DragManager.KeyDown(CharCode, ss);
     end;
   WM_KEYUP:
     if DragManager.IsDragging then begin
       CharCode := word(WParam);
       DragManager.KeyUp(CharCode, ss);
     end;
   end;
//this was the original code
    Result := Windows.DefWindowProc(Window, Msg, WParam, LParam);
end;

The Linux code may suffer from similar lack of propagating messages...

After some more tests I found a general problem with Win7: docked windows cannot be undocked any more, by dragging the DockHeader - even in very old Lazarus revisions. It looks to me as if something is seriously broken in the LCL :-(

The above DockWindow may be an attempt to cure some of these problems, but it does not address the real trouble source.

DoDi

Reply by email

Hans-Peter Diettrich
to Hans-Peter Diettrich: Since two weeks I'm offline, here some questions and comments about docking, in general…
In the 64 bit and SVN trunk version (32 bit) docking works much smoother, but the dockable IDE is a mess. The DragManager gets no keys, i.e. docking cannot be aborted with Esc.

See workaround in preceding message.

The dockable IDE is not dockable at all, i.e. the docked forms cannot be undocked or docked to other windows.

Fix for this problem (dragmanager.inc):

procedure TDragManagerDefault.CaptureChanged(OldCaptureControl: TControl);
{
var
   i: integer;
   AIsDragging,
   AIsDocking: Boolean;
}
begin
   // if this is TWinControl, and it have controls (not TWinControls)
   // then we should check Dragging in those controls
{$IFDEF old}
   AIsDocking := False;
   AIsDragging := OldCaptureControl.Dragging;
   if AIsDragging then
     AIsDocking := OldCaptureControl.DragKind = dkDock;
   if (not AIsDragging) and (OldCaptureControl is TWinControl) then
   begin
     for i := 0 to TWinControl(OldCaptureControl).ControlCount - 1 do
     begin
       AIsDragging := AIsDragging or
TWinControl(OldCaptureControl).Controls[i].Dragging;
       if AIsDragging then
       begin
         AIsDocking :=
TWinControl(OldCaptureControl).Controls[i].DragKind = dkDock;
         break;
       end;
     end;
   end;
   // when we are start drag/dock in TDockHeader then we should
   // take into account that it doesnot belong to our control - it
   // belongs to parent => we should allow parent to get capture
   if not (AIsDocking and (CaptureControl = OldCaptureControl.Parent)) then
     DragStop(AIsDragging);
{$ELSE}
   if (FPerformer = nil) or (CaptureControl = OldCaptureControl) then
     exit;
   if not (FPerformer is TDockPerformer) then
     exit;
   if assigned(CaptureControl) and (CaptureControl.Parent =
OldCaptureControl) then
     exit;
   DragStop(False);
{$ENDIF}
end;

Reply by email