Issue #176: do not close completion view on editor focus lost event jv
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 15 Dec 2017 08:49:11 +0000
branchjv
changeset 6348 bbae86d44915
parent 6279 232954e959f7
child 6349 4366b65a2c8a
Issue #176: do not close completion view on editor focus lost event ...if the currently focused view is the completion view. See the comment in #editViewLostFocus for rationale. See https://swing.fit.cvut.cz/projects/stx-jv/ticket/176
EditTextView.st
EditTextViewCompletionSupport.st
--- a/EditTextView.st	Fri Jan 26 11:43:24 2018 +0000
+++ b/EditTextView.st	Fri Dec 15 08:49:11 2017 +0000
@@ -6281,9 +6281,11 @@
     "/ completer. Otherwise, completion does not work when clocking into the list.
     explicit ifTrue:[
         completionSupport notNil ifTrue:[
-            completionSupport release.
-        ].
-    ].
+            completionSupport editViewLostFocus.
+        ].
+    ].
+
+    "Modified: / 15-12-2017 / 00:30:27 / jv"
 !
 
 wantsFocusWithPointerEnter
@@ -8105,10 +8107,12 @@
 !EditTextView methodsFor:'queries'!
 
 canAccept
-    "true if text can be accepts.
+    "true if text can be accepted.
      Used to disable the menu if there is nothing selector or the text is readonly"
 
-    ^ acceptEnabled ~~ false
+    ^ acceptEnabled ~~ false and:[ self isReadOnly not ]
+
+    "Modified: / 06-02-2018 / 15:32:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 canCut
@@ -8137,6 +8141,27 @@
     "Created: / 17.5.1998 / 20:07:52 / cg"
 !
 
+hasLanguage
+    "Returns `true` if the editor has a langiage associated, `false` otherwise.
+     Used to disable language-specific menu items items if there's no language."
+
+    ^ self editedLanguage notNil
+
+    "Created: / 06-02-2018 / 15:45:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hasLanguageToolbox
+    "Returns `true` if the editor has a langiage that has a 'toolbox', `false` otherwise.
+     Used to disable language-specific menu items if there's no `toolbox`."
+
+    | lang |
+
+    lang := self editedLanguage.
+    ^lang notNil and:[ lang toolbox notNil ]
+
+    "Created: / 06-02-2018 / 20:08:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 hasSearchActionSelection
 
     ^ typeOfSelection == #searchAction
--- a/EditTextViewCompletionSupport.st	Fri Jan 26 11:43:24 2018 +0000
+++ b/EditTextViewCompletionSupport.st	Fri Dec 15 08:49:11 2017 +0000
@@ -15,7 +15,7 @@
 documentation
 "
     An abstract supperclass to support completion in text views.
-    Individual completion engines may create a subclass of 
+    Individual completion engines may create a subclass of
     EditTextCompletionSupport and customize it.
 
     Basically, they have to implement #computeCompletions
@@ -66,6 +66,27 @@
      therefore, allow for the activate of the completionMenu and its button event to be processed.
      before forcing it to be closed..."
 
+    | focusedView |
+
+    "/ JV@2017-12-15: I don't really understand the problem and the solution.
+    "/ However, closing forcibly the completion view turned out to be a problem
+    "/ on Windows IF focus-follow-mouse is enabled:
+    "/
+    "/ When a completion view is opened, it may be opened just "below" the mouse
+    "/ so the completion view gets the focus and edit view looses it. Since
+    "/ edit view lost focus, this method is called and completion view is closed.
+    "/
+    "/ To handle this case, we do nothing IF focus switches to editor or
+    "/ the completion view itself.
+    "/
+    "/ See issue https://swing.fit.cvut.cz/projects/stx-jv/ticket/176
+    "/
+    focusedView := editView device focusView.
+    focusedView notNil ifTrue:[
+        focusedView == editView ifTrue:[ ^ self ].
+        focusedView topView == completionView ifTrue:[ ^ self ].
+    ].
+
     completionView notNil ifTrue:[
         editView graphicsDevice anyButtonPressed ifTrue:[
             editView sensor pushUserEvent:#editViewLostFocus for:self.
@@ -73,6 +94,9 @@
             self closeCompletionView
         ]
     ].
+
+    "Modified: / 15-12-2017 / 00:26:50 / jv"
+    "Modified (comment): / 15-12-2017 / 08:43:37 / jv"
 !
 
 handleKeyPress:key x:x y:y
@@ -112,12 +136,12 @@
             "/never
             eatCursorLeftOrRight := false.
 "/                                    completeImmediate not
-"/                                    or:[ editView sensor shiftDown 
+"/                                    or:[ editView sensor shiftDown
 "/                                    or:[ editView sensor ctrlDown ]].
             "/ only with shift or ctrl
-            eatCursorUpDown := 
+            eatCursorUpDown :=
                     (UserPreferences current codeCompletionViewKeyboardNavigationNeedsModifier not)
-                    or:[ editView sensor shiftDown 
+                    or:[ editView sensor shiftDown
                     or:[ editView sensor ctrlDown]].
 
             ((key == #CursorDown and:[eatCursorUpDown])
@@ -133,7 +157,7 @@
 
             (key == #Control_L or:[ key == #Control_R or:[ key == #Control or:[ key == #Ctrl ]]]) ifTrue:[
                 "/ CTRL is a toggle
-"/                self closeCompletionView.   
+"/                self closeCompletionView.
 "/                ^ true.
                 ^ false "/ don't eat
             ].
@@ -218,16 +242,16 @@
     "/ terminate any previous process
     self stopCompletionProcess.
 
-    (editView sensor hasKeyPressEventFor:nil) ifTrue:[ 
+    (editView sensor hasKeyPressEventFor:nil) ifTrue:[
         "/ 'cl' printCR.
-        self closeCompletionView. 
+        self closeCompletionView.
         ^ self
     ].
     ((cursorX := editView xOfCursor) isNil
     or:[ (cursorY := editView yOfCursor) isNil ]) ifTrue:[
         "/ no cursor - user is selecting, or cursor has been scrolled out of sight.
         "/ 'cl2' printCR.
-        self closeCompletionView. 
+        self closeCompletionView.
         ^ self
     ].
 
@@ -240,17 +264,17 @@
     ].
     self openCompletionView:initialList.
 
-    completionProcess := 
+    completionProcess :=
         [
             "/ protect end-user applications from errors
             Error handle:[:ex |
                 Smalltalk isSmalltalkDevelopmentSystem ifTrue:[ ex reject ]
-            ] do:[ 
+            ] do:[
                 (editView topView isDebugView) ifTrue:[
                     ControlInterrupt ignoreIn:[
                         self computeCompletions.
-                    ].    
-                ] ifFalse:[    
+                    ].
+                ] ifFalse:[
                     self computeCompletions.
                 ].
             ].
@@ -301,20 +325,20 @@
 
 openCompletionView: list
     "Makes sure the completion view is opened and with given `list`."
-    
-    | textCursorPosInTextView textCursorPosOnScreen movePos topView 
-      screenBounds screenBoundsCorner 
+
+    | textCursorPosInTextView textCursorPosOnScreen movePos topView
+      screenBounds screenBoundsCorner
       helpViewsExtent helpViewsWidth helpViewsHeight|
 
     "/ move the window away from the text cursor (to not cover what user types in)
     "/ get the screen-relative position of the text cursor
     textCursorPosInTextView := editView xOfCursor @ editView yOfCursor.
-    
-    "/ care for the scroll-offset (xOfCursor/yOFCursor gives me               
+
+    "/ care for the scroll-offset (xOfCursor/yOFCursor gives me
     textCursorPosInTextView := textCursorPosInTextView - (editView viewOrigin x @ 0).
-    
-    textCursorPosOnScreen := editView device 
-                    translatePoint:textCursorPosInTextView 
+
+    textCursorPosOnScreen := editView device
+                    translatePoint:textCursorPosInTextView
                     fromView:editView toView:nil.
 
     "/ currently, we have to stay away a bit, to avoid getting the focus
@@ -335,7 +359,7 @@
         completionView list:list.
         topView := completionView topView.
     ].
-    
+
     topView ~~ completionView ifTrue:[
         topView resizeToFit.
 
@@ -347,7 +371,7 @@
         helpViewsWidth := helpViewsExtent x.
         helpViewsHeight := helpViewsExtent y.
 
-        "/ if it does not lie completely inside the screen, move it     
+        "/ if it does not lie completely inside the screen, move it
         (movePos x + helpViewsWidth) > screenBoundsCorner x ifTrue:[
             movePos := (textCursorPosOnScreen x - 60 - helpViewsWidth) @ movePos y.
         ].
@@ -356,7 +380,7 @@
         ].
         movePos y < 0 ifTrue:[
             movePos := movePos x @ 0
-        ].    
+        ].
         topView origin:movePos.
     ].
 
@@ -372,5 +396,10 @@
 
 version_CVS
     ^ '$Header$'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
 ! !