@@ -44,6 +44,7 @@ function(wktProject, wktConsole, wdtDiscoverer, dialogHelper, projectIO,
4444 } ) ;
4545
4646 window . api . ipc . receive ( 'start-save-project' , ( ) => {
47+ blurSelection ( ) ;
4748 projectIO . saveProject ( true ) . catch ( err => {
4849 displayCatchAllError ( 'save-all' , err ) . then ( ) ;
4950 } ) ;
@@ -58,18 +59,21 @@ function(wktProject, wktConsole, wdtDiscoverer, dialogHelper, projectIO,
5859 } ) ;
5960
6061 window . api . ipc . receive ( 'start-offline-discover' , ( ) => {
62+ blurSelection ( ) ;
6163 wdtDiscoverer . startDiscoverDomain ( false ) . catch ( err => {
6264 displayCatchAllError ( 'discover' , err ) . then ( ) ;
6365 } ) ;
6466 } ) ;
6567
6668 window . api . ipc . receive ( 'start-online-discover' , ( ) => {
69+ blurSelection ( ) ;
6770 wdtDiscoverer . startDiscoverDomain ( true ) . catch ( err => {
6871 displayCatchAllError ( 'discover' , err ) . then ( ) ;
6972 } ) ;
7073 } ) ;
7174
7275 window . api . ipc . receive ( 'start-close-project' , ( ) => {
76+ blurSelection ( ) ;
7377 projectIO . closeProject ( false ) . catch ( err => {
7478 displayCatchAllError ( 'close-project' , err ) . then ( ) ;
7579 } ) ;
@@ -80,118 +84,146 @@ function(wktProject, wktConsole, wdtDiscoverer, dialogHelper, projectIO,
8084 } ) ;
8185
8286 window . api . ipc . receive ( 'blur-focused-item' , ( ) => {
83- document . activeElement . blur ( ) ;
87+ if ( document . activeElement ) {
88+ document . activeElement . blur ( ) ;
89+ }
8490 } ) ;
8591
8692 window . api . ipc . receive ( 'start-prepare-model' , async ( ) => {
93+ blurSelection ( ) ;
8794 wdtModelPreparer . startPrepareModel ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
8895 displayCatchAllError ( 'wdt-preparer-prepare' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
8996 } ) ;
9097 } ) ;
9198
9299 window . api . ipc . receive ( 'start-validate-model' , async ( ) => {
100+ blurSelection ( ) ;
93101 wdtModelValidator . startValidateModel ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
94102 displayCatchAllError ( 'wdt-validator-validate' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
95103 } ) ;
96104 } ) ;
97105
98106 window . api . ipc . receive ( 'start-create-image' , async ( ) => {
107+ blurSelection ( ) ;
99108 witImageCreator . startCreateImage ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
100109 displayCatchAllError ( 'wit-creator-create' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
101110 } ) ;
102111 } ) ;
103112
113+ window . api . ipc . receive ( 'start-push-image' , async ( ) => {
114+ blurSelection ( ) ;
115+ imagePusher . startPushImage ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
116+ displayCatchAllError ( 'image-pusher-push' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
117+ } ) ;
118+ } ) ;
119+
104120 window . api . ipc . receive ( 'start-create-aux-image' , async ( ) => {
121+ blurSelection ( ) ;
105122 witAuxImageCreator . startCreateAuxImage ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
106123 displayCatchAllError ( 'wit-creator-create-aux' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
107124 } ) ;
108125 } ) ;
109126
110127 window . api . ipc . receive ( 'start-push-aux-image' , async ( ) => {
128+ blurSelection ( ) ;
111129 auxImagePusher . startPushAuxImage ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
112- displayCatchAllError ( 'image-pusher-push-aux ' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
130+ displayCatchAllError ( 'aux- image-pusher-push' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
113131 } ) ;
114132 } ) ;
115133
116134 window . api . ipc . receive ( 'start-k8s-verify-connection' , async ( ) => {
135+ blurSelection ( ) ;
117136 k8sHelper . startVerifyClusterConnectivity ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
118137 displayCatchAllError ( 'kubectl-helper-verify-connect' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
119138 } ) ;
120139 } ) ;
121140
122141 window . api . ipc . receive ( 'start-wko-install' , async ( ) => {
142+ blurSelection ( ) ;
123143 wkoInstaller . startInstallOperator ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
124144 displayCatchAllError ( 'wko-installer-install' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
125145 } ) ;
126146 } ) ;
127147
128148 window . api . ipc . receive ( 'start-wko-update' , async ( ) => {
149+ blurSelection ( ) ;
129150 wkoUpdater . startUpdateOperator ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
130151 displayCatchAllError ( 'wko-updater-update' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
131152 } ) ;
132153 } ) ;
133154
134155 window . api . ipc . receive ( 'start-wko-uninstall' , async ( ) => {
156+ blurSelection ( ) ;
135157 wkoUninstaller . startUninstallOperator ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
136158 displayCatchAllError ( 'wko-uninstaller-install' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
137159 } ) ;
138160 } ) ;
139161
140162 window . api . ipc . receive ( 'start-k8s-domain-deploy' , async ( ) => {
163+ blurSelection ( ) ;
141164 k8sDomainDeployer . startDeployDomain ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
142165 displayCatchAllError ( 'k8s-domain-deployer-deploy' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
143166 } ) ;
144167 } ) ;
145168
146- window . api . ipc . receive ( 'get-wko-domain-status' , async ( ) => {
169+ window . api . ipc . receive ( 'start-get-k8s-domain-status' , async ( ) => {
170+ blurSelection ( ) ;
147171 k8sDomainStatusChecker . startCheckDomainStatus ( ) . then ( ( ) => { Promise . resolve ( ) ; } ) . catch ( err => {
148172 displayCatchAllError ( 'k8s-domain-status-checker-get-status' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
149173 } ) ;
150174 } ) ;
151175
152176 window . api . ipc . receive ( 'start-k8s-domain-undeploy' , async ( ) => {
177+ blurSelection ( ) ;
153178 k8sDomainUndeployer . startUndeployDomain ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
154179 displayCatchAllError ( 'k8s-domain-undeployer-undeploy' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
155180 } ) ;
156181 } ) ;
157182
158183 window . api . ipc . receive ( 'start-add-model-file' , async ( ) => {
184+ blurSelection ( ) ;
159185 projectIO . startAddModelFile ( ) . catch ( err => {
160186 displayCatchAllError ( 'add-model-file' , err ) . then ( ) ;
161187 } ) ;
162188 } ) ;
163189
164190 window . api . ipc . receive ( 'start-add-variable-file' , async ( ) => {
191+ blurSelection ( ) ;
165192 projectIO . startAddVariableFile ( ) . catch ( err => {
166193 displayCatchAllError ( 'add-variable-file' , err ) . then ( ) ;
167194 } ) ;
168195 } ) ;
169196
170197 window . api . ipc . receive ( 'start-add-archive-file' , async ( ) => {
198+ blurSelection ( ) ;
171199 projectIO . startAddArchiveFile ( ) . catch ( err => {
172200 displayCatchAllError ( 'add-archive-file' , err ) . then ( ) ;
173201 } ) ;
174202 } ) ;
175203
176204 window . api . ipc . receive ( 'start-ingress-install' , async ( ) => {
205+ blurSelection ( ) ;
177206 ingressControllerInstaller . startInstallIngressController ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
178207 displayCatchAllError ( 'ingress-installer-install' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
179208 } ) ;
180209 } ) ;
181210
182211 window . api . ipc . receive ( 'start-ingress-uninstall' , async ( ) => {
212+ blurSelection ( ) ;
183213 ingressControllerUninstaller . startUninstallIngressController ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
184214 displayCatchAllError ( 'ingress-uninstaller-uninstall' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
185215 } ) ;
186216 } ) ;
187217
188- window . api . ipc . receive ( 'add-ingress-routes' , async ( ) => {
218+ window . api . ipc . receive ( 'start-update-ingress-routes' , async ( ) => {
219+ blurSelection ( ) ;
189220 ingressRoutesUpdater . startIngressRoutesUpdate ( ) . then ( ( ) => Promise . resolve ( ) ) . catch ( err => {
190221 displayCatchAllError ( 'ingress-routes-updater-update-routes' , err ) . then ( ( ) => Promise . resolve ( ) ) ;
191222 } ) ;
192223 } ) ;
193224
194225 window . api . ipc . receive ( 'start-window-close' , async ( ) => {
226+ blurSelection ( ) ;
195227 return doDirtyCheck ( 'close-window' ) ;
196228 } ) ;
197229
@@ -204,6 +236,7 @@ function(wktProject, wktConsole, wdtDiscoverer, dialogHelper, projectIO,
204236 } ) ;
205237
206238 window . api . ipc . receive ( 'start-app-quit' , async ( ) => {
239+ blurSelection ( ) ;
207240 return doDirtyCheck ( 'window-app-quit' ) ;
208241 } ) ;
209242
@@ -234,6 +267,19 @@ function(wktProject, wktConsole, wdtDiscoverer, dialogHelper, projectIO,
234267 } ) ;
235268 }
236269
270+ /**
271+ * Remove keyboard focus from the active DOM element (macOS only).
272+ * This causes Ace editor and Jet controls to persist their current values.
273+ * This workaround is required because the menu-will-show event on the application menu
274+ * does not fire correctly on macOS, so the blur-focused-item IPC is not sent to the renderer.
275+ * See GitHub electron issue 31915.
276+ */
277+ function blurSelection ( ) {
278+ if ( window . api . process . isMac ( ) && document . activeElement ) {
279+ document . activeElement . blur ( ) ;
280+ }
281+ }
282+
237283 //////////////////////////////////////////////////////////////////////////////
238284 // Once all listeners are registered, send window-is-ready to: //
239285 // - notify electron know the window is ready to receive messages, and //
0 commit comments