View Issue Details

IDProjectCategoryView StatusLast Update
0027007LazarusWidgetsetpublic2014-12-02 13:37
ReporterZeljan RikaloAssigned ToZeljan Rikalo 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.3 (SVN)Product Build46763 
Target Version1.2.8Fixed in Version1.3 (SVN) 
Summary0027007: Gtk2: Modal windows problem under compositing manager
Descriptionhttp://forum.lazarus.freepascal.org/index.php/topic,26371.0.html

Problem is with wm's which doesn't use internal transiency code (kwin,awesome).
Tested on Fedora 20 64bit.
TagsNo tags attached.
Fixed in Revision47057
LazTarget1.2.8
WidgetsetGTK 2
Attached Files
  • gtk2_modal_forms.diff (1,281 bytes)
    Index: lcl/interfaces/gtk2/gtk2wsforms.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wsforms.pp	(revision 46763)
    +++ lcl/interfaces/gtk2/gtk2wsforms.pp	(working copy)
    @@ -69,6 +69,7 @@
       protected
         class procedure SetCallbacks(const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual;
       published
    +    class procedure CloseModal(const ACustomForm: TCustomForm); override;
         class function  CanFocus(const AWinControl: TWinControl): Boolean; override;
         class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
         class procedure ScrollBy(const AWinControl: TScrollingWinControl; const DeltaX, DeltaY: integer); override;
    @@ -332,6 +333,15 @@
         gtk_signal_func(@Gtk2FormEvent), AWidgetInfo^.LCLObject);
     end;
     
    +class procedure TGtk2WSCustomForm.CloseModal(const ACustomForm: TCustomForm);
    +begin
    +  {$IFDEF HASX}
    +  if ACustomForm.HandleAllocated and (GTK2WidgetSet.GetDesktopWidget <> nil) and
    +    gtk_window_get_modal(PGtkWindow(ACustomForm.Handle)) then
    +      gtk_window_set_modal(PGtkWindow(ACustomForm.Handle), False);
    +  {$ENDIF}
    +end;
    +
     class function TGtk2WSCustomForm.CanFocus(const AWinControl: TWinControl
       ): Boolean;
     var
    
    gtk2_modal_forms.diff (1,281 bytes)
  • hidebeforeuntransient.diff (1,989 bytes)
    Index: gtk2proc.inc
    ===================================================================
    --- gtk2proc.inc	(révision 46966)
    +++ gtk2proc.inc	(copie de travail)
    @@ -3483,6 +3483,7 @@
       {$IFDEF VerboseTransient}
       DebugLn('DestroyCommonDialogAddOns ',DbgSName(ADialog));
       {$ENDIF}
    +  gtk_widget_hide(DlgWindow);
       gtk_window_set_transient_for(PGtkWindow(DlgWindow),nil);
       if ADialog is TOpenDialog then begin
         FileSelWidget:=GTK_FILE_CHOOSER(DlgWindow);
    Index: gtk2wsforms.pp
    ===================================================================
    --- gtk2wsforms.pp	(révision 46966)
    +++ gtk2wsforms.pp	(copie de travail)
    @@ -684,6 +684,7 @@
       AForm: TCustomForm;
       GtkWindow: PGtkWindow;
       Geometry: TGdkGeometry;
    +  UnTransient : boolean;
     
       function ShowNonModalOverModal: Boolean;
       var
    @@ -732,6 +733,7 @@
         GtkWindowShowModal(AForm, GtkWindow);
       end else
       begin
    +    UnTransient:=false;
         if ShowNonModalOverModal then begin
           // issue #21459
         end
    @@ -743,14 +745,12 @@
           and (AForm.PopupParent = nil) and (AForm.BorderStyle = bsNone)
         then begin
           // showing a non modal form with bsNone above a modal form
    -      gtk_window_set_transient_for(GtkWindow, nil);
    +      UnTransient:=true;
           gtk_window_set_modal(GtkWindow, True);
         end else begin
           // hiding/showing normal form
           // clear former mods, e.g. when a modal form becomes a normal form, see bug 23876
    -      // hide before disable modal see bug 27070
    -      Gtk2WidgetSet.SetVisible(AWinControl, AForm.HandleObjectShouldBeVisible);
    -      gtk_window_set_transient_for(GtkWindow, nil); //untransient
    +      UnTransient:=true;
           gtk_window_set_modal(GtkWindow, False);
         end;
     
    @@ -775,6 +775,10 @@
         {$ENDIF}
     
         Gtk2WidgetSet.SetVisible(AWinControl, AForm.HandleObjectShouldBeVisible);
    +    if UnTransient then
    +    Begin
    +      gtk_window_set_transient_for(gtkWindow, nil);
    +    End;
       end;
     
       if not (csDesigning in AForm.ComponentState) and
    
  • mixedpatch.diff (1,409 bytes)
    Index: lcl/interfaces/gtk2/gtk2proc.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.inc	(révision 46966)
    +++ lcl/interfaces/gtk2/gtk2proc.inc	(copie de travail)
    @@ -3483,6 +3483,9 @@
       {$IFDEF VerboseTransient}
       DebugLn('DestroyCommonDialogAddOns ',DbgSName(ADialog));
       {$ENDIF}
    +  {$IFDEF HASX}
    +  gtk_window_set_modal(PGtkWindow(DlgWindow),false);
    +  {$ENDIF}
       gtk_window_set_transient_for(PGtkWindow(DlgWindow),nil);
       if ADialog is TOpenDialog then begin
         FileSelWidget:=GTK_FILE_CHOOSER(DlgWindow);
    Index: lcl/interfaces/gtk2/gtk2wsforms.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wsforms.pp	(révision 46966)
    +++ lcl/interfaces/gtk2/gtk2wsforms.pp	(copie de travail)
    @@ -748,10 +748,13 @@
         end else begin
           // hiding/showing normal form
           // clear former mods, e.g. when a modal form becomes a normal form, see bug 23876
    -      // hide before disable modal see bug 27070
    -      Gtk2WidgetSet.SetVisible(AWinControl, AForm.HandleObjectShouldBeVisible);
    +      {$IFDEF HASX}
    +      gtk_window_set_modal(GtkWindow, False);
           gtk_window_set_transient_for(GtkWindow, nil); //untransient
    +      {$ELSE}
    +      gtk_window_set_transient_for(GtkWindow, nil); //untransient
           gtk_window_set_modal(GtkWindow, False);
    +      {$ENDIF}
         end;
     
         {$IFDEF HASX}
    
    mixedpatch.diff (1,409 bytes)

Relationships

has duplicate 0027070 closedMattias Gaertner problem with modal form in IDE and project compiled with gtk2 

Activities

Zeljan Rikalo

2014-11-06 15:26

developer  

gtk2_modal_forms.diff (1,281 bytes)
Index: lcl/interfaces/gtk2/gtk2wsforms.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wsforms.pp	(revision 46763)
+++ lcl/interfaces/gtk2/gtk2wsforms.pp	(working copy)
@@ -69,6 +69,7 @@
   protected
     class procedure SetCallbacks(const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual;
   published
+    class procedure CloseModal(const ACustomForm: TCustomForm); override;
     class function  CanFocus(const AWinControl: TWinControl): Boolean; override;
     class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
     class procedure ScrollBy(const AWinControl: TScrollingWinControl; const DeltaX, DeltaY: integer); override;
@@ -332,6 +333,15 @@
     gtk_signal_func(@Gtk2FormEvent), AWidgetInfo^.LCLObject);
 end;
 
+class procedure TGtk2WSCustomForm.CloseModal(const ACustomForm: TCustomForm);
+begin
+  {$IFDEF HASX}
+  if ACustomForm.HandleAllocated and (GTK2WidgetSet.GetDesktopWidget <> nil) and
+    gtk_window_get_modal(PGtkWindow(ACustomForm.Handle)) then
+      gtk_window_set_modal(PGtkWindow(ACustomForm.Handle), False);
+  {$ENDIF}
+end;
+
 class function TGtk2WSCustomForm.CanFocus(const AWinControl: TWinControl
   ): Boolean;
 var
gtk2_modal_forms.diff (1,281 bytes)

Zeljan Rikalo

2014-11-06 15:26

developer   ~0078961

Patch fixes forms, but not dialogs yet. Please test.

Juha Manninen

2014-11-08 10:34

developer   ~0079002

it works well. Cool!

Zeljan Rikalo

2014-11-08 21:19

developer   ~0079024

Not so cool. It doesn't work for dialogs

Cedric

2014-11-22 23:23

reporter   ~0079302

Last edited: 2014-11-23 11:01

View 2 revisions

can someone test this patch ? it's work fine on my computer for dialog and form.

hidebeforeuntransient.diff

Zeljan Rikalo

2014-11-23 10:25

developer   ~0079306

@Cedric, that part with dialogs from your patch maybe could work, but please explain why your patch is better than mine in case of forms. Have you tested it with various window managers (eg. kwin, metacity, mate, openbox, xfce ... etc) ?
Also, patch should not be submitted in this way, but attached.

Cedric

2014-11-23 11:01

reporter  

hidebeforeuntransient.diff (1,989 bytes)
Index: gtk2proc.inc
===================================================================
--- gtk2proc.inc	(révision 46966)
+++ gtk2proc.inc	(copie de travail)
@@ -3483,6 +3483,7 @@
   {$IFDEF VerboseTransient}
   DebugLn('DestroyCommonDialogAddOns ',DbgSName(ADialog));
   {$ENDIF}
+  gtk_widget_hide(DlgWindow);
   gtk_window_set_transient_for(PGtkWindow(DlgWindow),nil);
   if ADialog is TOpenDialog then begin
     FileSelWidget:=GTK_FILE_CHOOSER(DlgWindow);
Index: gtk2wsforms.pp
===================================================================
--- gtk2wsforms.pp	(révision 46966)
+++ gtk2wsforms.pp	(copie de travail)
@@ -684,6 +684,7 @@
   AForm: TCustomForm;
   GtkWindow: PGtkWindow;
   Geometry: TGdkGeometry;
+  UnTransient : boolean;
 
   function ShowNonModalOverModal: Boolean;
   var
@@ -732,6 +733,7 @@
     GtkWindowShowModal(AForm, GtkWindow);
   end else
   begin
+    UnTransient:=false;
     if ShowNonModalOverModal then begin
       // issue #21459
     end
@@ -743,14 +745,12 @@
       and (AForm.PopupParent = nil) and (AForm.BorderStyle = bsNone)
     then begin
       // showing a non modal form with bsNone above a modal form
-      gtk_window_set_transient_for(GtkWindow, nil);
+      UnTransient:=true;
       gtk_window_set_modal(GtkWindow, True);
     end else begin
       // hiding/showing normal form
       // clear former mods, e.g. when a modal form becomes a normal form, see bug 23876
-      // hide before disable modal see bug 27070
-      Gtk2WidgetSet.SetVisible(AWinControl, AForm.HandleObjectShouldBeVisible);
-      gtk_window_set_transient_for(GtkWindow, nil); //untransient
+      UnTransient:=true;
       gtk_window_set_modal(GtkWindow, False);
     end;
 
@@ -775,6 +775,10 @@
     {$ENDIF}
 
     Gtk2WidgetSet.SetVisible(AWinControl, AForm.HandleObjectShouldBeVisible);
+    if UnTransient then
+    Begin
+      gtk_window_set_transient_for(gtkWindow, nil);
+    End;
   end;
 
   if not (csDesigning in AForm.ComponentState) and

Cedric

2014-11-23 11:09

reporter   ~0079307

Last edited: 2014-11-23 11:14

View 3 revisions

sorry, i attached the patch, i never say it's better then your's.

I only tested it on KDE.

The method is the same for form and dialog (hide the form/dialog before the transient control was erased. I think the wm use the transient control to highlight grayed window when a modal window is closed/hidden).

Perhaps yours patch can be updated for working on dialog.

Cedric

2014-11-23 20:53

reporter   ~0079317

Last edited: 2014-11-23 21:10

View 3 revisions

if i analyse your patch correctly, it's equivalent to invert the calling sequence in TGtk2WSCustomForm.ShowHide :

      gtk_window_set_transient_for(GtkWindow, nil); //untransient
      gtk_window_set_modal(GtkWindow, False);

actually your patch is same as :

      gtk_window_set_modal(GtkWindow, False);
[...]
      gtk_window_set_transient_for(GtkWindow, nil); //untransient
      gtk_window_set_modal(GtkWindow, False);

i think it's better to modify directly TGtk2WSCustomForm.ShowHide , because with your patch gtk_window_set_modal(GtkWindow, False); is called twice.

perhaps an :

{$IFDEF HASX }
      gtk_window_set_modal(GtkWindow, False);
      gtk_window_set_transient_for(GtkWindow, nil); //untransient
{$ELSE}
      gtk_window_set_transient_for(GtkWindow, nil); //untransient
      gtk_window_set_modal(GtkWindow, False);
{$ENDIF}

i tried it on my kde, it's work.

Cedric

2014-11-23 21:10

reporter   ~0079318

Last edited: 2014-11-23 21:36

View 3 revisions

from your patch and mine, i deduce this (for dialogs) :
insert : gtk_window_set_modal(PGtkWindow(DlgWindow), False);
before : gtk_window_set_transient_for(PGtkWindow(DlgWindow),nil);
in gtk2proc.inc.DestroyCommonDialogAddOns should work.

i tried that on my kde, it's work.

Cedric

2014-11-23 21:48

reporter  

mixedpatch.diff (1,409 bytes)
Index: lcl/interfaces/gtk2/gtk2proc.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.inc	(révision 46966)
+++ lcl/interfaces/gtk2/gtk2proc.inc	(copie de travail)
@@ -3483,6 +3483,9 @@
   {$IFDEF VerboseTransient}
   DebugLn('DestroyCommonDialogAddOns ',DbgSName(ADialog));
   {$ENDIF}
+  {$IFDEF HASX}
+  gtk_window_set_modal(PGtkWindow(DlgWindow),false);
+  {$ENDIF}
   gtk_window_set_transient_for(PGtkWindow(DlgWindow),nil);
   if ADialog is TOpenDialog then begin
     FileSelWidget:=GTK_FILE_CHOOSER(DlgWindow);
Index: lcl/interfaces/gtk2/gtk2wsforms.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wsforms.pp	(révision 46966)
+++ lcl/interfaces/gtk2/gtk2wsforms.pp	(copie de travail)
@@ -748,10 +748,13 @@
     end else begin
       // hiding/showing normal form
       // clear former mods, e.g. when a modal form becomes a normal form, see bug 23876
-      // hide before disable modal see bug 27070
-      Gtk2WidgetSet.SetVisible(AWinControl, AForm.HandleObjectShouldBeVisible);
+      {$IFDEF HASX}
+      gtk_window_set_modal(GtkWindow, False);
       gtk_window_set_transient_for(GtkWindow, nil); //untransient
+      {$ELSE}
+      gtk_window_set_transient_for(GtkWindow, nil); //untransient
       gtk_window_set_modal(GtkWindow, False);
+      {$ENDIF}
     end;
 
     {$IFDEF HASX}
mixedpatch.diff (1,409 bytes)

Zeljan Rikalo

2014-11-24 08:55

developer   ~0079330

@Cedric, I know that it should work on kde, metacity and xfce should be tested before commiting.

Cedric

2014-11-24 11:53

reporter   ~0079345

@Zeljan Rikalo , no problem i never asked to commit this patch. I joined it for tests.

i'm suprised that my patch for issue 0027070 was comitted !
I'm beginner with lazarus / LCL i started played with it two week ago ;)

I can test it on xcfe.

Zeljan Rikalo

2014-11-24 13:06

developer   ~0079350

Yes, please test but with compositing enabled.

Cedric

2014-11-25 11:17

reporter   ~0079380

Last edited: 2014-11-25 11:21

View 2 revisions

trunk not patched (revert on issue 0027070 ) :

XCFE 4.10 (xubuntu)
with compositing : OK
without compositing : OK

KDE 4.13.3 (kubuntu)
with compositing : KO
without compositing : OK


trunk patched with mixedpatch.diff

XCFE 4.10 (xubuntu)
with compositing : OK
without compositing : OK

KDE 4.13.3 (kubuntu)
with compositing : OK
without compositing : OK

Zeljan Rikalo

2014-12-02 09:39

developer   ~0079560

Please test and close if ok.

Issue History

Date Modified Username Field Change
2014-11-06 15:10 Zeljan Rikalo New Issue
2014-11-06 15:10 Zeljan Rikalo Assigned To => Zeljan Rikalo
2014-11-06 15:10 Zeljan Rikalo Status new => assigned
2014-11-06 15:26 Zeljan Rikalo File Added: gtk2_modal_forms.diff
2014-11-06 15:26 Zeljan Rikalo Note Added: 0078961
2014-11-08 10:34 Juha Manninen Note Added: 0079002
2014-11-08 21:19 Zeljan Rikalo Note Added: 0079024
2014-11-22 10:35 Juha Manninen Relationship added has duplicate 0027070
2014-11-22 23:23 Cedric Note Added: 0079302
2014-11-23 10:25 Zeljan Rikalo Note Added: 0079306
2014-11-23 11:01 Cedric Note Edited: 0079302 View Revisions
2014-11-23 11:01 Cedric File Added: hidebeforeuntransient.diff
2014-11-23 11:09 Cedric Note Added: 0079307
2014-11-23 11:10 Cedric Note Edited: 0079307 View Revisions
2014-11-23 11:14 Cedric Note Edited: 0079307 View Revisions
2014-11-23 20:53 Cedric Note Added: 0079317
2014-11-23 20:55 Cedric Note Edited: 0079317 View Revisions
2014-11-23 21:10 Cedric Note Added: 0079318
2014-11-23 21:10 Cedric Note Edited: 0079317 View Revisions
2014-11-23 21:24 Cedric Note Edited: 0079318 View Revisions
2014-11-23 21:36 Cedric Note Edited: 0079318 View Revisions
2014-11-23 21:48 Cedric File Added: mixedpatch.diff
2014-11-24 08:55 Zeljan Rikalo Note Added: 0079330
2014-11-24 11:53 Cedric Note Added: 0079345
2014-11-24 13:06 Zeljan Rikalo Note Added: 0079350
2014-11-25 11:17 Cedric Note Added: 0079380
2014-11-25 11:21 Cedric Note Edited: 0079380 View Revisions
2014-12-02 09:39 Zeljan Rikalo Fixed in Revision => 47057
2014-12-02 09:39 Zeljan Rikalo LazTarget - => 1.2.8
2014-12-02 09:39 Zeljan Rikalo Note Added: 0079560
2014-12-02 09:39 Zeljan Rikalo Status assigned => resolved
2014-12-02 09:39 Zeljan Rikalo Fixed in Version => 1.3 (SVN)
2014-12-02 09:39 Zeljan Rikalo Resolution open => fixed
2014-12-02 13:37 Zeljan Rikalo Status resolved => closed