[Cuis-dev] [FIX] Don't lose Keyboard Focus

Gerald Klix cuis.01 at klix.ch
Thu Dec 2 10:43:11 PST 2021


Hi all, Hi Juan,

Please find attached a fix for the lost keyboard focus
(https://lists.cuis.st/mailman/archives/cuis-dev/2021-November/004490.html).

It introduces the concept of a keyboard focus catcher, SystemWindows
for example or panels. The catchers catch the keyboard focus,
if the current morph does not handle keyboard events.


HTH and Best Regards,

Gerald
-------------- next part --------------
'From Haver 5.0 [latest update: #4995] on 2 December 2021 at 7:35:45 pm'!

!Morph methodsFor: 'focus handling' stamp: 'KLG 12/2/2021 16:18:50'!
catchesKeyboardFocus
	"Answer true if I catch the keyboard focus, if no one else wants it.
	
	Morphs that are containes that handle events for the whole assembly,
	should answer true.
	
	Needed for SystemWindows to always enable Ctrl/Cmd-W to close the window
	and such."

	^ false! !


!SystemWindow methodsFor: 'focus handling' stamp: 'KLG 12/2/2021 16:19:42'!
catchesKeyboardFocus
	"Answer true if I catch the keyboard focus, if no one else wants it.
	
	Morphs that are containes that handle events for the whole assembly,
	should answer true.
	
	Needed for SystemWindows to always enable Ctrl/Cmd-W to close the window
	and such."

	^ true! !


!Morph methodsFor: 'events-processing' stamp: 'KLG 12/2/2021 19:28:19'!
processMouseEnter: aMouseEvent localPosition: localEventPosition
	"System level event handling."

	aMouseEvent isDraggingEvent ifTrue: [
		^self].
	self wantsBalloon ifTrue: [
		aMouseEvent hand triggerBalloonFor: self after: self balloonHelpDelayTime ].
	self handlesMouseOver: aMouseEvent ::
		ifTrue: [
			aMouseEvent wasHandled: true.
			self mouseEnter: aMouseEvent ]
		ifFalse: [
			"Catch the keyboard focus, if we are a catcher."
			Preferences focusFollowsMouse and: [ self catchesKeyboardFocus ] ::
				ifTrue: [ aMouseEvent hand newKeyboardFocus: self ] ]			! !

!Morph methodsFor: 'events-processing' stamp: 'KLG 12/2/2021 19:26:09'!
processMouseLeave: anEvent localPosition: localEventPosition
	"System level event handling."
	
	anEvent hand removePendingBalloonFor: self.
	anEvent isDraggingEvent ifTrue: [
		^self].
	self handlesMouseOver: anEvent ::
		ifTrue: [
			anEvent wasHandled: true.
			self mouseLeave: anEvent ]
		ifFalse: [
			"Maybe we caught the keyboard focus, release it, just in case."
			Preferences focusFollowsMouse and: [ self catchesKeyboardFocus ] ::
				ifTrue: [ anEvent hand releaseKeyboardFocus: self ] ]
! !


!HandMorph methodsFor: 'focus handling' stamp: 'KLG 12/2/2021 19:31:56'!
releaseKeyboardFocus: aMorph
	"If the given morph had the keyboard focus before, release it"

	keyboardFocus ifNotNil: [ | morphFound catcher |
		morphFound _ false.
		keyboardFocus withAllOwnersDo: [ :outerOwner |
			morphFound
				ifFalse: [
					outerOwner == aMorph ifTrue: [				morphFound _ true ] ]
				ifTrue: [
					catcher ifNil: [
						outerOwner catchesKeyboardFocus ifTrue: [
							catcher _ outerOwner ] ] ] ].
		morphFound ifTrue: [
			catcher
				ifNil: [ 	self releaseKeyboardFocus ]
				ifNotNil: [ self newKeyboardFocus: catcher ] ] ]! !


!SystemWindow reorganize!
('GUI building' buttonColor defaultButtonPaneHeight textBackgroundColor windowColor)
('change reporting' invalidateTitleArea)
('drawing' drawLabelOn: drawOn: makeMeFullyVisible makeMeVisible visible:)
('events' wantsToBeDroppedInto:)
('geometry' fontPreferenceChanged justDroppedInto:event: minimumExtent rescaleButtons)
('geometry services' on:ifCovered:uncoveredPartsDo:else:)
('initialization' createCloseButton createCollapseButton createExpandButton createMenuButton defaultBorderWidth defaultColor initialize initializeLabelArea openInWorld)
('label' label labelHeight relabel setLabel: update:)
('layout' beColumn beRow layoutMorph layoutSubmorphs)
('menu' addCustomMenuItems:hand: addTileResizerMenuTo: addWindowControlTo: buildWindowMenu changeColor fullScreen makeSecondTopmost offerWindowMenu sendToBack setWindowColor setWindowColor:)
('open/close' closeBoxHit delete initialExtent initialFrameIn: openInWorld:)
('panes' widgetsColor widgetsColor: windowFrameColor)
('printing' printOn:)
('resize/collapse' allowedArea expandBoxHit resize resize: resizeBottom resizeBottomLeft resizeBottomRight resizeFull resizeLeft resizeRight resizeTop resizeTopLeft resizeTopRight)
('resizing' windowBottom: windowBottomLeft: windowBottomRight: windowLeft: windowRight: windowTop: windowTopLeft: windowTopRight:)
('stepping' stepAt: stepTime wantsSteps wantsStepsWhenCollapsed)
('structure' owningWindow)
('submorphs-accessing')
('submorphs-add/remove' addMorph: addMorph:layoutSpec:)
('testing' is:)
('top window' activate activateAndForceLabelToShow activateAndSendTopToBack: isTopWindow submorphToFocusKeyboard)
('user interface' canDiscardEditsOf: hasSaveAs isItOkToLooseChanges notifyUserWith: okToChange okToChangeDueTo: saveContents saveContentsTo:)
('focus handling' drawClassicFrameOn:color: drawRoundedFrameOn:color: shouldIndicateKeyboardFocus submorphHasKeyboardFocus catchesKeyboardFocus)
!



More information about the Cuis-dev mailing list