<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body>
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p>Ouch, sorry for the inconvenience. Thank you for fixing this! Still works for me on both Windows + Linux. :-)</p>
<p><br>
</p>
<p>Best,</p>
<p>Christoph</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Chris Muller <asqueaker@gmail.com><br>
<b>Gesendet:</b> Mittwoch, 1. Juni 2022 02:20:37<br>
<b>An:</b> squeak dev<br>
<b>Cc:</b> packages@lists.squeakfoundation.org<br>
<b>Betreff:</b> Re: [squeak-dev] The Trunk: Morphic-tonyg.1997.mcz</font>
<div> </div>
</div>
<div>
<div dir="ltr">OMG, THANK YOU!  I suffered by this for how Magma opens multiple images to run its test suite.  Whenever the suite would fail, it's a pain to get all the windows closed, I almost sure, because of this bug.  I searched high and low for the cause,
 but was never able to track it down.  Great work!</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, May 24, 2022 at 3:03 AM <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>> wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Tony Garnock-Jones uploaded a new version of Morphic to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Morphic-tonyg.1997.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/Morphic-tonyg.1997.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Morphic-tonyg.1997<br>
Author: tonyg<br>
Time: 24 May 2022, 9:56:56.627629 am<br>
UUID: ea8cb549-5895-4ad8-8fde-4fcb6ea5594e<br>
Ancestors: Morphic-ct.1996<br>
<br>
Repair bug that caused unconditional clearing of the #mouseOverForKeyboardFocus preference whenever the host window was de/reactivated.<br>
<br>
Symptoms: switching away from Squeak and back (or save-and-quit followed by reopen) while #mouseOverForKeyboardFocus enabled would cause it to become disabled.<br>
<br>
Cause: PasteUpMorph>>#windowEvent: was clearing the preference and then restoring it from state in a WindowHostFocusMorph. However, when #windowDeactivated occurred twice in a row (which happens), it would correctly store #mouseOverForKeyboardFocus in the first
 WindowHostFocusMorph instance, but then would deactivate and replace that instance with a fresh one, which would then receive the incorrect (false) value of #mouseOverForKeyboardFocus. Later, when the window was activated again, the incorrect value would be
 restored, because the correct value had already been forgotten (as it was contained in the first, rather than the second-and-current, WindowHostFocusMorph instance).<br>
<br>
Change: Alter WindowHostFocusMorph>>#active: to not only set the active instvar but to save or restore the #mouseOverForKeyboardFocus preference. This way, any time a WindowHostFocusMorph is activated, the preference is saved, and any time it is deactivated,
 the preference is restored. This works with the current logic in PasteUpMorph>>#windowEvent:. One drawback is that it repeatedly toggles the preference, depending on how many redundant de/reactivation events the host sends us in a row, but the final value
 of the preference is at least correct now (I hope!).<br>
<br>
=============== Diff against Morphic-ct.1996 ===============<br>
<br>
Item was changed:<br>
  ----- Method: PasteUpMorph>>windowEvent: (in category 'event handling') -----<br>
  windowEvent: anEvent<br>
<br>
        self windowEventHandler<br>
                ifNotNil: [^self windowEventHandler windowEvent: anEvent].<br>
<br>
        anEvent type<br>
                caseOf: {<br>
                        [#windowClose] -> [<br>
                                Preferences eToyFriendly <br>
                                        ifTrue: [ProjectNavigationMorph basicNew quitSqueak]<br>
                                        ifFalse: [TheWorldMenu basicNew quitSession]].<br>
<br>
                        [#windowDeactivated]    -> [<br>
+                               "The host window has been deactivated. Until it regains the focus, honor the fact that we will not receive keyboard events again by changing the current keyboard focus morph. windowHostFocusMorph represents the host system which
 now holds the keyboard focus instead of the previousFocus."<br>
-                               "The host window has been deactivated. Until it regains the focus, honor the fact that we will not receive keyboard events again by changing the current keyboard focus morph. windowHostFocusMorph represents the host system which
 now holds the keyboard focus instead of the previousFocus. If enabled, disable #mouseOverForKeyboardFocus temporarily because when inactive, we *can't* set the externally controlled keyboard focus."<br>
                                (self valueOfProperty: #windowHostFocusMorph) ifNotNil: [:hostFocus |<br>
                                        "There is currently no exact-once guarantee for this event type from the VM. Mark any older host focus morph as inactive, it will be held as the previousFocus of the next host focus morph."<br>
                                        hostFocus active: false].<br>
                                self setProperty: #windowHostFocusMorph toValue: (WindowHostFocusMorph new<br>
                                        in: [:hostFocus |<br>
                                                hostFocus previousFocus: anEvent hand keyboardFocus.<br>
+                                               anEvent hand newKeyboardFocus: hostFocus.];<br>
-                                               anEvent hand newKeyboardFocus: hostFocus.<br>
-                                               Preferences mouseOverForKeyboardFocus ifTrue: [<br>
-                                                       hostFocus previousMouseOverForKeyboardFocus: true.<br>
-                                                       Preferences setPreference: #mouseOverForKeyboardFocus toValue: false]];<br>
                                        yourself)].<br>
                        [#windowActivated] -> [<br>
+                               "Alright, the spook is over!! We have back control over the keyboard focus, delete the windowHostFocusMorph and restore the previous focus holder."<br>
-                               "Alright, the spook is over!! We have back control over the keyboard focus, delete the windowHostFocusMorph and restore the previous focus holder and the #mouseOverForKeyboardFocus preference."<br>
                                (self removeProperty: #windowHostFocusMorph) ifNotNil: [:hostFocus |<br>
                                        hostFocus active: false.<br>
                                        (anEvent hand keyboardFocus == hostFocus and: [hostFocus previousFocus notNil]) ifTrue:<br>
+                                               [anEvent hand newKeyboardFocus: hostFocus previousFocus]]]. }<br>
-                                               [anEvent hand newKeyboardFocus: hostFocus previousFocus].<br>
-                                       hostFocus previousMouseOverForKeyboardFocus ifNotNil: [:value |<br>
-                                               Preferences setPreference: #mouseOverForKeyboardFocus toValue: value]]]. }<br>
                otherwise: []!<br>
<br>
Item was changed:<br>
  ----- Method: WindowHostFocusMorph>>active: (in category 'accessing') -----<br>
  active: aBoolean<br>
+       active := aBoolean.<br>
<br>
+       active<br>
+               ifTrue: [<br>
+                       "If #mouseOverForKeyboardFocus is enabled, disable it temporarily because when WindowHostFocusMorph 'has the focus', Squeak as a whole *doesn't*, and we *can't* set the externally controlled keyboard focus."<br>
+                       self saveMouseOverForKeyboardFocus]<br>
+               ifFalse: [<br>
+                       "Restore the #mouseOverForKeyboardFocus preference that we (maybe) saved when we were activated."<br>
+                       self restoreMouseOverForKeyboardFocus]!<br>
-       active := aBoolean.!<br>
<br>
Item was removed:<br>
- ----- Method: WindowHostFocusMorph>>previousMouseOverForKeyboardFocus (in category 'accessing') -----<br>
- previousMouseOverForKeyboardFocus<br>
- <br>
-       ^ previousMouseOverForKeyboardFocus!<br>
<br>
Item was removed:<br>
- ----- Method: WindowHostFocusMorph>>previousMouseOverForKeyboardFocus: (in category 'accessing') -----<br>
- previousMouseOverForKeyboardFocus: aBoolean<br>
- <br>
-       previousMouseOverForKeyboardFocus := aBoolean.!<br>
<br>
Item was added:<br>
+ ----- Method: WindowHostFocusMorph>>restoreMouseOverForKeyboardFocus (in category 'accessing') -----<br>
+ restoreMouseOverForKeyboardFocus<br>
+       previousMouseOverForKeyboardFocus ifNotNil: [:value |<br>
+               previousMouseOverForKeyboardFocus := nil.<br>
+               Preferences setPreference: #mouseOverForKeyboardFocus toValue: value].!<br>
<br>
Item was added:<br>
+ ----- Method: WindowHostFocusMorph>>saveMouseOverForKeyboardFocus (in category 'accessing') -----<br>
+ saveMouseOverForKeyboardFocus<br>
+       Preferences mouseOverForKeyboardFocus ifTrue: [<br>
+               previousMouseOverForKeyboardFocus := true.<br>
+               Preferences setPreference: #mouseOverForKeyboardFocus toValue: false].!<br>
<br>
<br>
</blockquote>
</div>
</div>
</body>
</html>