[Lazarus] Desktops and multiple source editors

Ondrej Pokorny lazarus at kluug.net
Wed Sep 9 17:16:33 CEST 2015

On 09.09.2015 12:58, Juha Manninen wrote:
> Martin Friebe noticed a problem with desktops and multiple source
> editor windows.
> In fact I also noticed that a second source editor is not restored
> correctly when changing desktops.
> Now I realized the 2nd, 3rd etc. editor windows are project specific,
> while other layout settings are global. This is not very logical. How
> to solve it?
> I think all layout settings should be global for the sake of consistency.
> Juha

The settings are saved correctly in the environment settings. Try to 
save a desktop with 2 editor windows, move something (including the 
editor windows) and then load the desktop. Both editor windows are 
positioned correctly.

Actually, from the principal point of view, the code is correct. Editor 
windows are normal nonmodal windows and so they are restored/closed on 
desktop change like any other window. If you stored a desktop without a 
secondary editor window, it is closed when you apply the desktop.

But I see that this is not wanted and expected from the user's point of 
view ->
That means secondary editor windows need special treatment in 
It should not change visibility of editor windows. It should only change 
their position.

I fixed this in the undocked environment. See the patch. Please 
test/comment. The special windows that should not be closed/shown on 
desktop change have to be registered in the 
*IDEWindowsDontChangeVisibility* list (names of the forms). Currently 
only editor windows are added into the list.
Important: if you save a desktop with a secondary editor and use it, the 
position of the secondary editor is restored. If you save a desktop with 
no secondary editors and you apply the desktop when there is a secondary 
editor window visible, it won't change its position. This is correct 

+ Please don't report bugs like "I created a desktop with no editor 
window. But when I apply it, the editor window isn't closed." This is 
the requested behavior now (there is no difference between 
secondary/primary editor window).

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20150909/daa1df1a/attachment-0003.html>
-------------- next part --------------
Index: components/ideintf/idewindowintf.pas
--- components/ideintf/idewindowintf.pas	(revision 49796)
+++ components/ideintf/idewindowintf.pas	(working copy)
@@ -233,6 +233,7 @@
     procedure LoadFromConfig(Config: TConfigStorage; const Path: string);
     procedure SaveToConfig(Config: TConfigStorage; const Path: string);
     function CustomCoordinatesAreValid: boolean;
+    function DefaultCoordinatesAreValid: boolean;
     procedure CloseForm;
     function ValidateAndSetCoordinates(const aForce: Boolean = False): Boolean;
     procedure SetDefaultPosition(const AForm: TCustomForm);
@@ -483,6 +484,7 @@
 procedure MakeIDEWindowDockable(AControl: TWinControl);
 procedure MakeIDEWindowDockSite(AForm: TCustomForm);
 procedure CloseAllForms;
+function IDEWindowsDontChangeVisibility: TStringList;
 procedure Register;
@@ -491,6 +493,9 @@
+  FIDEWindowsDontChangeVisibility: TStringList = nil;
 function StrToIDEWindowPlacement(const s: string): TIDEWindowPlacement;
   for Result:=Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do
@@ -551,6 +556,16 @@
+function IDEWindowsDontChangeVisibility: TStringList;
+  if not Assigned(FIDEWindowsDontChangeVisibility) then
+  begin
+    FIDEWindowsDontChangeVisibility := TStringList.Create;
+    FIDEWindowsDontChangeVisibility.Sorted := True;
+  end;
+  Result := FIDEWindowsDontChangeVisibility;
 procedure Register;
@@ -1199,6 +1214,11 @@
   Result:=(Width>0) and (Height>0); // and (Left>10-Width) and (Top>10-Height);
+function TSimpleWindowLayout.DefaultCoordinatesAreValid: boolean;
+  Result:=(DefaultWidth>0) and (DefaultHeight>0);
 procedure TSimpleWindowLayout.CloseForm;
@@ -1214,8 +1234,11 @@
   Result := False;
   if aForce or CustomCoordinatesAreValid then begin
     if not CustomCoordinatesAreValid then//default position
+    begin
+      if not DefaultCoordinatesAreValid then//don't change the coordinates if default position is invalid
+        Exit;
       NewBounds := Bounds(DefaultLeft, DefaultTop, DefaultWidth, DefaultHeight)
-    else// explicit position
+    end else// explicit position
       NewBounds := Bounds(Left, Top, Width, Height);
     // set minimum size
@@ -2239,6 +2262,7 @@
   i: Integer;
   ALayout: TSimpleWindowLayout;
   AForm: TCustomForm;
+  AChangeVisibility: Boolean;
   if IDEDockMaster=nil then
@@ -2245,13 +2269,21 @@
     for i:=SimpleLayoutStorage.Count-1 downto 0 do//loop down in order to keep z-order of the forms
-      AForm:=GetForm(ALayout.FormID,ALayout.Visible);
+      AChangeVisibility := (IDEWindowsDontChangeVisibility.IndexOf(ALayout.FormID) = -1);
+      AForm:=GetForm(ALayout.FormID,AChangeVisibility and ALayout.Visible);
       if AForm=nil then Continue;
-      ALayout.Apply(True);
-      if ALayout.Visible or (AForm=Application.MainForm) then
-        ShowForm(AForm,true)
-      else if AForm.Visible then
-        AForm.Close;
+      ALayout.Apply(AChangeVisibility);
+      if AChangeVisibility then
+      begin
+        if ALayout.Visible or (AForm=Application.MainForm) then
+          ShowForm(AForm,true)
+        else if AForm.Visible then
+          AForm.Close;
+      end else
+      begin//do not change visibility
+        if AForm.Visible then//Only make sure their z-index is OK if they are already visible
+          ShowForm(AForm,true)
+      end;
@@ -2294,6 +2326,7 @@
+  FreeAndNil(FIDEWindowsDontChangeVisibility);
Index: ide/sourceeditor.pp
--- ide/sourceeditor.pp	(revision 49796)
+++ ide/sourceeditor.pp	(working copy)
@@ -5740,6 +5740,7 @@
     Name := NonModalIDEWindowNames[nmiwSourceNoteBookName] + IntToStr(AWindowID+1)
     Name := NonModalIDEWindowNames[nmiwSourceNoteBookName];
+  IDEWindowsDontChangeVisibility.Add(Name);
   if AWindowID > 0 then
     FBaseCaption := locWndSrcEditor + ' (' + IntToStr(AWindowID+1) + ')'

More information about the Lazarus mailing list