From 3d198d213f67d75398bb5184a8abf5d10b6e9e00 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 13 Nov 2019 10:44:23 +1100 Subject: [PATCH 1/7] fix(windows): focus is incorrect for CEF The focus code paths for Chromium frames (CEF4Delphi) were incorrect. The return value for preventing focus on navigation events was inverted, and then other code was attempting to work around this inversion, wrongly. Fixed the root issue of the inverted test (it would help if the parameter cefSetFocus was known as `Handled` rather than `Result`!) and then the remaining code pathways became far simpler. Fixes #2314. --- .../Keyman.Developer.UI.UframeCEFHost.dfm | 1 - .../Keyman.Developer.UI.UframeCEFHost.pas | 29 ++++--------------- .../developer/TIKE/main/UframeTextEditor.pas | 1 - 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.dfm b/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.dfm index bdbacd30c4..b326cf9e21 100644 --- a/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.dfm +++ b/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.dfm @@ -34,7 +34,6 @@ inherited frameCEFHost: TframeCEFHost Top = 208 end object cef: TChromium - OnWidgetCompMsg = cefWidgetCompMsg OnLoadEnd = cefLoadEnd OnSetFocus = cefSetFocus OnRunContextMenu = cefRunContextMenu diff --git a/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.pas b/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.pas index 818205d189..63d0138cfb 100644 --- a/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.pas +++ b/windows/src/developer/TIKE/main/Keyman.Developer.UI.UframeCEFHost.pas @@ -35,7 +35,6 @@ const CEF_AFTERCREATE = WM_USER + 302; CEF_SHOW = WM_USER + 303; CEF_LOADEND = WM_USER + 304; - CEF_SETFOCUS = WM_USER + 305; CEF_KEYEVENT = WM_USER + 306; CEF_BEFOREBROWSE = WM_USER + 307; CEF_CONSOLEMESSAGE = WM_USER + 308; @@ -106,7 +105,6 @@ type var settings: TCefBrowserSettings; var noJavascriptAccess: Boolean; var Result: Boolean); - procedure cefWidgetCompMsg(var aMessage: TMessage; var aHandled: Boolean); procedure cefSetFocus(Sender: TObject; const browser: ICefBrowser; source: TCefFocusSource; out Result: Boolean); private @@ -134,7 +132,6 @@ type procedure Handle_CEF_AFTERCREATE(var Message: TMessage); procedure Handle_CEF_SHOW(var message: TMessage); procedure Handle_CEF_LOADEND(var message: TMessage); - procedure Handle_CEF_SETFOCUS(var message: TMessage); procedure Handle_CEF_KEYEVENT(var message: TMessage); procedure Handle_CEF_BEFOREBROWSE(var message: TMessage); procedure Handle_CEF_CONSOLEMESSAGE(var message: TMessage); @@ -268,14 +265,6 @@ begin CreateBrowser; end; -procedure TframeCEFHost.cefWidgetCompMsg(var aMessage: TMessage; - var aHandled: Boolean); -begin - AssertCefThread; - if aMessage.Msg = WM_SETFOCUS then - PostMessage(FCallbackWnd, CEF_SETFOCUS, 0, 0); -end; - procedure TframeCEFHost.CreateBrowser; begin AssertVclThread; @@ -308,9 +297,11 @@ end; procedure TframeCEFHost.SetFocus; begin AssertVclThread; - inherited; - if not FIsClosing and cefwp.CanFocus then - cefwp.SetFocus; + if not FIsClosing and cefwp.CanFocus and Assigned(cef) then + begin + GetParentForm(Self).ActiveControl := Self; + cef.SetFocus(True); + end; end; procedure TframeCEFHost.CallbackWndProc(var Message: TMessage); @@ -322,7 +313,6 @@ begin CEF_AFTERCREATE: Handle_CEF_AFTERCREATE(Message); CEF_SHOW: Handle_CEF_SHOW(Message); CEF_LOADEND: Handle_CEF_LOADEND(Message); - CEF_SETFOCUS: Handle_CEF_SETFOCUS(Message); CEF_KEYEVENT: Handle_CEF_KEYEVENT(Message); CEF_BEFOREBROWSE: Handle_CEF_BEFOREBROWSE(Message); CEF_CONSOLEMESSAGE: Handle_CEF_CONSOLEMESSAGE(Message); @@ -534,13 +524,6 @@ begin FOnLoadEnd(Self); end; -procedure TframeCEFHost.Handle_CEF_SETFOCUS(var message: TMessage); -begin - AssertVclThread; - if Assigned(cefwp) and cefwp.Visible and cefwp.CanFocus then - GetParentForm(cefwp).ActiveControl := cefwp; -end; - procedure TframeCEFHost.cefPreKeyEvent(Sender: TObject; const browser: ICefBrowser; const event: PCefKeyEvent; osEvent: PMsg; out isKeyboardShortcut, Result: Boolean); @@ -614,7 +597,7 @@ end; procedure TframeCEFHost.cefSetFocus(Sender: TObject; const browser: ICefBrowser; source: TCefFocusSource; out Result: Boolean); begin - Result := source <> FOCUS_SOURCE_NAVIGATION; + Result := source = FOCUS_SOURCE_NAVIGATION; end; procedure TframeCEFHost.WMEnterMenuLoop(var aMessage: TMessage); diff --git a/windows/src/developer/TIKE/main/UframeTextEditor.pas b/windows/src/developer/TIKE/main/UframeTextEditor.pas index 5b97d4b8f3..fca4d88760 100644 --- a/windows/src/developer/TIKE/main/UframeTextEditor.pas +++ b/windows/src/developer/TIKE/main/UframeTextEditor.pas @@ -656,7 +656,6 @@ end; procedure TframeTextEditor.SetFocus; begin - inherited; cef.SetFocus; end; From bdd2cb90341fac7d83ea0865fca068567e2a2548 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 15 Nov 2019 11:08:00 +1100 Subject: [PATCH 2/7] chore(developer): history.md --- windows/src/developer/history.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/windows/src/developer/history.md b/windows/src/developer/history.md index cfbc63ea89..69c69d909a 100644 --- a/windows/src/developer/history.md +++ b/windows/src/developer/history.md @@ -3,6 +3,9 @@ ## 13.0 alpha * Start version 13.0 +## 2019-11-15 12.0.54 stable +* Bug Fix: Text editor and other controls did not receive focus correctly (#2331) + ## 2019-10-07 12.0.50 stable * Release 12.0 From b31baa4f9f9010e1b5183e8baba8952a303716ea Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 13 Nov 2019 08:28:14 +1100 Subject: [PATCH 3/7] fix(windows): OSK restores to wrong monitor If the On Screen Keyboard was closed when on a monitor other than the primary monitor, it would restore to the primary monitor in the top- left corner instead of the previous location. This fix allows the OSK to be restored to another monitor, but still avoids positioning the window off screen if the monitor has been disconnected. Fixes #2270. --- .../keyman/viskbd/UfrmVisualKeyboard.pas | 62 +++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas index 9417d4597c..5205cc0b54 100644 --- a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas +++ b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas @@ -280,6 +280,8 @@ type implementation uses + System.Types, + CommCtrl, GraphUtil, KeymanHints, @@ -303,7 +305,7 @@ uses VistaMessages, MessageIdentifierConsts, messageidentifiers, - BitmapIPicture, Types; + BitmapIPicture; {$R *.DFM} @@ -1331,12 +1333,62 @@ begin end; procedure TfrmVisualKeyboard.LoadSettings; - procedure MoveBounds(R: TRect); + function FitRectInBounds(R, BR: TRect): TRect; begin - if (R.Left < R.Right) and (R.Top < R.Bottom) and (R.Left >= 0) and (R.Top >= 0) and - (R.Bottom <= Screen.Height) and (R.Right <= Screen.Width) then - BoundsRect := R; + if R.Width > BR.Width then + R.Width := BR.Width; + + if R.Height > BR.Height then + R.Height := BR.Height; + + if R.Left < BR.Left then + R.Offset(BR.Left-R.Left, 0); + + if R.Right > BR.Right then + R.Offset(BR.Right-R.Right, 0); + + if R.Top < BR.Top then + R.Offset(0, BR.Top-R.Top); + + if R.Bottom > BR.Bottom then + R.Offset(0, BR.Bottom-R.Bottom); + + Result := R; end; + + procedure MoveBounds(R: TRect); + var + area, i: Integer; + m: Integer; + BR, RI: TRect; + begin + // Adjust the rectangle to ensure TopLeft <= BottomRight + R.NormalizeRect; + + // Move the rect onto the screen (e.g. when monitor is disconnected, + // we don't want to show the OSK off the screen). It is valid for the window + // rect to go negative, if for example primary monitor is not left-most. + + // If the OSK is partially on-screen, move it onto the monitor where it has + // the most real-estate. + m := 0; area := 0; + for i := 0 to Screen.MonitorCount - 1 do + begin + if System.Types.IntersectRect(RI, R, Screen.Monitors[i].BoundsRect) then + begin + if RI.Width * RI.Height > area then + begin + area := RI.Width * RI.Height; + m := i; + end; + end; + end; + + BR := Screen.Monitors[m].WorkareaRect; + + Self.BoundsRect := FitRectInBounds(R, BR); + end; + procedure MoveDefault; begin SetBounds(Screen.WorkAreaRect.Right - Width, Screen.WorkAreaRect.Bottom - Height, Width, Height); From fb29d5ba59701583d8a51f5ab57cffe86720b6cb Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 15 Nov 2019 11:12:54 +1100 Subject: [PATCH 4/7] chore(windows): history.md --- windows/src/desktop/history.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/windows/src/desktop/history.md b/windows/src/desktop/history.md index 2700822cc0..7a93845e62 100644 --- a/windows/src/desktop/history.md +++ b/windows/src/desktop/history.md @@ -3,6 +3,9 @@ ## 13.0 alpha * Start version 13.0 +## 2019-11-15 12.0.54 stable +* Bug Fix: On Screen Keyboard restored to wrong screen and position when reloading (#2330) + ## 2019-11-12 12.0.53 stable * Bug Fix: Address instability when exiting Keyman on some systems (#2324) * Bug Fix: Keyman was not working with Skype, Windows Search on some systems (#2324) From 0cfb842b06b3f6e0b047f14f092949fd7bb2a862 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 13 Nov 2019 13:23:55 +1100 Subject: [PATCH 5/7] fix(developer): keyboard_info merge mobile wrong The .keyboard_info merge of `platformSupport` would not always give the right result, for .js keyboards. We have a certain lack of information in the .js which makes it a little tricky to determine precisely what the set of supported platforms are. Thus, if we find a .js within a .kmp, we'll assume it supports mobile; if we find a .js by itself, we'll assume it supports web. (Thus, a keyboard that builds a .js is assumed to always support web -- but not necessarily mobile now). Some keyboards that have incorrectly added a .js into a package, e.g. sil_cipher_music, will be marked as supporting mobile even though they don't. The correct fix here is to remove the .js from the package for that keyboard. --- .../TIKE/compile/MergeKeyboardInfo.pas | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/windows/src/developer/TIKE/compile/MergeKeyboardInfo.pas b/windows/src/developer/TIKE/compile/MergeKeyboardInfo.pas index 9dba8db6a0..fb2e2f5bb3 100644 --- a/windows/src/developer/TIKE/compile/MergeKeyboardInfo.pas +++ b/windows/src/developer/TIKE/compile/MergeKeyboardInfo.pas @@ -326,9 +326,11 @@ begin SetLength(FPackageJSFileInfos, Length(FPackageJSFileInfos)+1); FPackageJSFileInfos[High(FPackageJSFileInfos)].Filename := Zip.FileNames[j]; - // For now, apply JS keyboard to all web and mobile targets + // Apply JS keyboard only to mobile targets, because web is not supported + // in a package. If a package does not support mobile, it should not include + // the .js. // Not using GetKeyboardInfo because that only handles kmx files - FPackageJSFileInfos[High(FPackageJSFileInfos)].Info.Targets := 'web mobile'; + FPackageJSFileInfos[High(FPackageJSFileInfos)].Info.Targets := 'mobile'; end; end; end; @@ -975,8 +977,6 @@ begin AddNewPair('windows', 'full'); AddNewPair('macos', 'full'); AddNewPair('linux', 'full'); - AddNewPair('desktopWeb', 'full'); - AddNewPair('mobileWeb', 'full'); AddNewPair('android', 'full'); AddNewPair('ios', 'full'); end @@ -1007,11 +1007,6 @@ begin // FPackageKMXFileInfos can contain target information for web/mobile targets. // This is a current limitation of FPackageJSFileInfos if there's no kmx files - if target = ktWeb then - begin - AddNewPair('desktopWeb', 'full'); - AddNewPair('mobileWeb', 'full'); - end; if (target = ktMobile) then begin AddNewPair('android', 'full'); @@ -1034,11 +1029,6 @@ begin targets := StringToKeymanTargets(keyboardFile.Info.Targets); for target in targets do begin - if (target = ktWeb) then - begin - AddNewPair('desktopWeb', 'full'); - AddNewPair('mobileWeb', 'full'); - end; if (target = ktMobile) then begin AddNewPair('android', 'full'); @@ -1055,16 +1045,17 @@ begin end; end; - // Handle JS file not in kmp - if FJsFile <> '' then + // Handle JS file not in kmp. Because it is isolated, we cannot detect + // whether it supports mobile vs desktop web because that is not included + // in the .js. So, for now we assume both. + // + // We no longer assume that the presence of a .js means support for + // native mobile apps. These apps now work on the basis of having a + // .kmp file available + if (FJsFile <> '') then begin AddNewPair('desktopWeb', 'full'); AddNewPair('mobileWeb', 'full'); - - // TODO: Don't add Android and iOS when we complete the addition of all .js keyboards - // to packages in the repository (including legacy keyboards) - AddNewPair('android', 'full'); - AddNewPair('ios', 'full'); end; json.AddPair('platformSupport', v); From d4edfaa5a42f86302d6c865d76a7b57291a88047 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 15 Nov 2019 13:50:29 +1100 Subject: [PATCH 6/7] chore(developer): history.md --- windows/src/developer/history.md | 1 + 1 file changed, 1 insertion(+) diff --git a/windows/src/developer/history.md b/windows/src/developer/history.md index 69c69d909a..0d5e43778a 100644 --- a/windows/src/developer/history.md +++ b/windows/src/developer/history.md @@ -5,6 +5,7 @@ ## 2019-11-15 12.0.54 stable * Bug Fix: Text editor and other controls did not receive focus correctly (#2331) +* Bug Fix: Some keyboards were incorrectly marked as mobile-capable (#2334) ## 2019-10-07 12.0.50 stable * Release 12.0 From 4150f3d5ecbfd0335de5f134348070afa78dc20a Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 18 Nov 2019 08:59:07 +1100 Subject: [PATCH 7/7] Update history.md --- windows/src/developer/history.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/windows/src/developer/history.md b/windows/src/developer/history.md index 0d5e43778a..8b0628b00f 100644 --- a/windows/src/developer/history.md +++ b/windows/src/developer/history.md @@ -3,9 +3,11 @@ ## 13.0 alpha * Start version 13.0 +## 2019-11-18 12.0.55 stable +* Bug Fix: Some keyboards were incorrectly marked as mobile-capable (#2334) + ## 2019-11-15 12.0.54 stable * Bug Fix: Text editor and other controls did not receive focus correctly (#2331) -* Bug Fix: Some keyboards were incorrectly marked as mobile-capable (#2334) ## 2019-10-07 12.0.50 stable * Release 12.0 @@ -810,4 +812,4 @@ * Modern Windows Installer for straightforward deployment * Windows Vista support * Unicode support throughout Keyman Developer -* Automated online updates \ No newline at end of file +* Automated online updates