From 5c06d59a5e96ff48f67ef7c5642f884ee723a5de Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 29 Jul 2022 11:22:30 +1000 Subject: [PATCH 01/31] fix(developer): compiler emitting garbage for readonly groups Picked up while reviewing code for conversion to C++. The compiler could, in some circumstances emit garbage code for readonly groups because we weren't testing all scenarios correctly. In practice, this would have been rare as readonly groups don't emit characters, but it should be fixed! --- developer/src/tike/compile/CompileKeymanWeb.pas | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/developer/src/tike/compile/CompileKeymanWeb.pas b/developer/src/tike/compile/CompileKeymanWeb.pas index f45651d22ba..c5966127349 100644 --- a/developer/src/tike/compile/CompileKeymanWeb.pas +++ b/developer/src/tike/compile/CompileKeymanWeb.pas @@ -1038,7 +1038,8 @@ function TCompileKeymanWeb.JavaScript_OutputString(FTabstops: string; fkp: PFILE begin if InQuotes then begin - Result := Result + '");'; + if not fgp.fReadOnly then + Result := Result + '");'; InQuotes := False; end; @@ -1223,9 +1224,9 @@ function TCompileKeymanWeb.JavaScript_OutputString(FTabstops: string; fkp: PFILE InQuotes := True; len := -1; end; - if rec.ChrVal in [Ord('"'), Ord('\')] then Result := Result + '\'; if not fgp.fReadOnly then begin + if rec.ChrVal in [Ord('"'), Ord('\')] then Result := Result + '\'; Result := Result + Javascript_String(rec.ChrVal); // I2242 end; end; @@ -1233,7 +1234,13 @@ function TCompileKeymanWeb.JavaScript_OutputString(FTabstops: string; fkp: PFILE pwsz := incxstr(pwsz); end; - if InQuotes then Result := Result + '");'; + if InQuotes then + begin + if not fgp.fReadOnly then + begin + Result := Result + '");'; + end; + end; end; function TCompileKeymanWeb.JavaScript_Shift(fkp: PFILE_KEY; FMnemonic: Boolean): Integer; From f9240d76a2db5fb370bb7fbabdf2293c10b4cb46 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 3 Aug 2022 12:53:03 -0500 Subject: [PATCH 02/31] fix(developer): stack overflow when compiling non-web keyboard Fixes #7030. Prevents a stack overflow / loop when the web target is removed from a keyboard and it has already been tested on web, and the user presses the Compile button. --- .../Keyman.Developer.UI.Project.kmnProjectFileUI.pas | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas b/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas index 57481848c20..9b2dd467c5b 100644 --- a/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas +++ b/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas @@ -67,6 +67,7 @@ implementation UfrmKeymanWizard, UfrmKeyboardFonts, UfrmMDIEditor, + UKeymanTargets, UmodWebHttpServer, Keyman.Developer.System.ServerAPI, Keyman.Developer.UI.ServerUI, @@ -133,7 +134,8 @@ function TkmnProjectFileUI.CompileKeyboard(FSilent: Boolean): Boolean; if Result and TServerDebugAPI.Running and - TServerDebugAPI.IsKeyboardRegistered(ProjectFile.TargetFileName) then + TServerDebugAPI.IsKeyboardRegistered(ProjectFile.TargetFileName) and + (ProjectFile.Targets * KMWKeymanTargets <> []) then TestKeymanWeb(True); end; @@ -235,7 +237,13 @@ function TkmnProjectFileUI.TestKeymanWeb(FSilent: Boolean): Boolean; // I4409 Exit(False); wizard := editor as TfrmKeymanWizard; + if ProjectFile.Targets * KMWKeymanTargets = [] then + Exit(False); + FCompiledName := ProjectFile.JSTargetFilename; + if FCompiledName = '' then + Exit(False); + if not TestKeyboardState(FCompiledName, FSilent) then Exit(False); From e5bd4e0be3d5c49f1e51153967a4c098a301a442 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 3 Aug 2022 12:57:34 -0500 Subject: [PATCH 03/31] fix(developer): prevent crash attempting to compile ansi keyboard Fixes #7032. --- developer/src/tike/compile/CompileKeymanWeb.pas | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/developer/src/tike/compile/CompileKeymanWeb.pas b/developer/src/tike/compile/CompileKeymanWeb.pas index f45651d22ba..c5088f0772d 100644 --- a/developer/src/tike/compile/CompileKeymanWeb.pas +++ b/developer/src/tike/compile/CompileKeymanWeb.pas @@ -2200,11 +2200,11 @@ function TCompileKeymanWeb.WriteCompiledKeyboard: string; {UTF8} { Write the groups out } // I853 - begin unicode missing causes crash -{ if fk.StartGroup[BEGIN_UNICODE] = $FFFFFFFF then + if fk.StartGroup[BEGIN_UNICODE] = $FFFFFFFF then begin - FCallback(fkp.Line, $4005, PChar('A "begin unicode" statement is required to compile a KeymanWeb keyboard')); + ReportError(0, CERR_InvalidBegin, 'A "begin unicode" statement is required to compile a KeymanWeb keyboard'); Exit; - end;} + end; Result := Result + WriteBeginStatement('gs', fk.StartGroup[BEGIN_UNICODE]); rec := ExpandSentinel(PChar(sBegin_NewContext)); From e8caeda643c937ba49a69a48eade01130fb93251 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 4 Aug 2022 11:43:14 +0700 Subject: [PATCH 04/31] fix(web): button, float init timer cleanup --- web/source/kmwuibutton.ts | 304 +++++++++++++++++++------------------- web/source/kmwuifloat.ts | 16 +- 2 files changed, 163 insertions(+), 157 deletions(-) diff --git a/web/source/kmwuibutton.ts b/web/source/kmwuibutton.ts index 23958dcc3a0..7591d4a95f0 100644 --- a/web/source/kmwuibutton.ts +++ b/web/source/kmwuibutton.ts @@ -6,7 +6,7 @@ // If a UI module has been loaded, we can rely on the publically-published 'name' property // having been set as a way to short-out a UI reload. Its parent object always exists by // this point in the build process. -if(!window['keyman']['ui']['name']) { +if(!window['keyman']['ui']['name']) { /********************************/ /* */ @@ -21,126 +21,127 @@ if(!window['keyman']['ui']['name']) { * Instead, use the --output-wrapper command during optimization, which will * add the anonymous function to enclose all code, including those optimized * variables which would otherwise have global scope. - **/ + **/ try { // Declare KeymanWeb, OnScreen keyboard and Util objects var keymanweb=window['keyman'], util=keymanweb['util'],dbg=keymanweb['debug']; - + // Disable UI for touch devices if(util['isTouchDevice']()) throw ''; - - // User interface global and variables + + // User interface global and variables keymanweb['ui'] = {}; var ui=keymanweb['ui']; ui['name'] = 'button'; - - ui.init = false; + + ui.init = false; + ui.initTimer = null; ui.KeyboardSelector = null; ui.KeymanWeb_DefaultKeyboardHelp='KeymanWeb is not running. Choose a keyboard from the list'; - ui._KeymanWeb_KbdList = null; - ui._KMWSel = null; - ui._IsHelpVisible = false; + ui._KeymanWeb_KbdList = null; + ui._KMWSel = null; + ui._IsHelpVisible = false; ui._DefaultKeyboardID = ''; ui.updateTimer = null; ui.updateList = true; - + /** * Highlight the currently active keyboard in the list of keyboards - **/ + **/ ui._ShowSelected = function() { - var _rv,kbd=keymanweb['getActiveKeyboard'](),lgc=keymanweb['getActiveLanguage'](), + var _rv,kbd=keymanweb['getActiveKeyboard'](),lgc=keymanweb['getActiveLanguage'](), kList = ui._KeymanWeb_KbdList.childNodes, _r = /^KMWSel_(.*)\$(.*)$/; - + for(var i=1; i= kList.length) i=1; - kList[i].childNodes[0].className = 'selected'; - } - + } + if(i >= kList.length) i=1; + kList[i].childNodes[0].className = 'selected'; + } + /** * Select keyboard by id - * + * * @param {Event} _id keyboard selection event - * @return {boolean} + * @return {boolean} */ ui._SelectKeyboard = function(_id) - { - if(typeof(_id) == 'object') + { + if(typeof(_id) == 'object') { var t=null; if((typeof(_id.target) != 'undefined') && _id.target) t=_id.target; - else if((typeof(_id.srcElement) != 'undefined') && _id.srcElement) t=_id.srcElement; + else if((typeof(_id.srcElement) != 'undefined') && _id.srcElement) t=_id.srcElement; if(t) _id=t.id; } - - var _r=/^KMWSel_(.*)\$(.*)$/; + + var _r=/^KMWSel_(.*)\$(.*)$/; var _rv=_r.exec(_id),_lgc='',_name=''; - if(_rv !== null) + if(_rv !== null) { _name = _rv[1].split('$')[0]; //new code - _lgc = _id.split('$')[1]; + _lgc = _id.split('$')[1]; if(ui._KMWSel != null) ui._KMWSel.className = ''; - var _k = document.getElementById(_id); - if(_k) _k.className='selected'; - ui._KMWSel = _k; + var _k = document.getElementById(_id); + if(_k) _k.className='selected'; + ui._KMWSel = _k; keymanweb['setActiveKeyboard'](_name,_lgc); } - else + else _name=null; - + keymanweb['focusLastActiveElement'](); let osk = keymanweb.osk; - if(osk && osk['isEnabled']()) osk['show'](true); + if(osk && osk['isEnabled']()) osk['show'](true); ui._ShowKeyboardButton(_name); return false; - } + } /** * Set KMW UI activation state on mouse click - * + * * @param {Event} e event - */ + */ ui._SelectorMouseDown = function(e) - { - var x=keymanweb['getLastActiveElement'](); + { + var x=keymanweb['getLastActiveElement'](); // Set the focus to an input field, to get correct OSK display behaviour if(!x) ui._FocusFirstInput(); else keymanweb['focusLastActiveElement'](); - + if(keymanweb['activatingUI']) keymanweb['activatingUI'](1); } /** * Set focus on mouse up - * + * * @param {Event} e event - */ + */ ui._SelectorMouseUp = function(e) - { + { var x=keymanweb['getLastActiveElement'](); - + // Set the focus to an input field, to get correct OSK display behaviour if(!x) ui._FocusFirstInput(); else keymanweb['focusLastActiveElement'](); } /** * Set KMW UI activation state on mouse over - * + * * @param {Event} e event - */ + */ ui._SelectorMouseOver = function(e) { // highlight the currently active keyboard @@ -155,21 +156,21 @@ if(!window['keyman']['ui']['name']) { /** * Sets the focus to the first input or textarea found on the current page - * to ensure consistent keyboard selection and OSK display behaviour - */ + * to ensure consistent keyboard selection and OSK display behaviour + */ ui._FocusFirstInput = function() { var i,ip=null,tp=null, iList=document.getElementsByTagName("input"), tList=document.getElementsByTagName("textarea"); - + for(i=0; i 0) tp = tList[0]; - + if((!ip) && (!tp)) return; else if(ip && !tp) @@ -185,12 +186,12 @@ if(!window['keyman']['ui']['name']) { else tp.focus(); } - + /** * Clear KMW UI activation state on mouse out - * + * * @param {Event} e event - */ + */ ui._SelectorMouseOut = function(e) { if(keymanweb['activatingUI']) keymanweb['activatingUI'](0); @@ -199,9 +200,9 @@ if(!window['keyman']['ui']['name']) { /** * Disable the button to show/hide the OSK if no active keyboard or active keyboard is CJK (user cannot hide) - * + * * @param {?string=} _name current keyboard name - */ + */ ui._ShowKeyboardButton = function(_name) { var kbdName = keymanweb['getActiveKeyboard'](), kbdId=document.getElementById("KMW_Keyboard"); @@ -209,17 +210,17 @@ if(!window['keyman']['ui']['name']) { if(kbdId) { if((kbdName == '') || keymanweb['isCJK']()) - { + { kbdId.className='kmw_disabled'; - } + } else { let osk = keymanweb.osk; kbdId.className = osk && osk['isEnabled']() ? 'kmw_show' : 'kmw_hide'; } } - } - + } + ui.registerEvents = function() { let osk = keymanweb.osk; if(!osk) { @@ -227,72 +228,79 @@ if(!window['keyman']['ui']['name']) { } /** * UI Functions called by KeymanWeb or OSK - */ - osk['addEventListener']('show', function(oskPosition) { + */ + osk['addEventListener']('show', function(oskPosition) { var t=keymanweb['getLastActiveElement'](); if(t) - { + { if(!oskPosition['userLocated']) { oskPosition['x'] = util['getAbsoluteX'](t); oskPosition['y'] = util['getAbsoluteY'](t)+t.offsetHeight; } - } - + } + ui._ShowKeyboardButton(); - return oskPosition; - }); + return oskPosition; + }); - /* TODO: why is this still needed??? Does it actually do anything?? */ - osk['addEventListener']('hide', function(hiddenByUser) { + /* TODO: why is this still needed??? Does it actually do anything?? */ + osk['addEventListener']('hide', function(hiddenByUser) { if((arguments.length > 0) && hiddenByUser) { var _a = document.getElementById('KMW_Keyboard'); if(_a) _a.className = 'kmw_hide'; - } - }); + } + }); } - + /** * Show or hide the OSK (always visible for CJK keyboards) - * + * * @param {Object} _anchor anchor element (?) - * @return {boolean} - **/ - ui._ShowKeymanWebKeyboard = function(_anchor) - { + * @return {boolean} + **/ + ui._ShowKeymanWebKeyboard = function(_anchor) + { var kbdId=document.getElementById("KMW_Keyboard"); let osk = keymanweb.osk; - if((kbdId.className!='kmw_disabled') && osk && osk['show']) + if((kbdId.className!='kmw_disabled') && osk && osk['show']) { if(osk['isEnabled']()) osk['hide'](); else osk['show'](true); } if(window.event) window.event.returnValue=false; - keymanweb['focusLastActiveElement'](); - return false; + keymanweb['focusLastActiveElement'](); + return false; } /** * Initialize Button User Interface - **/ + **/ ui['initialize'] = ui.Initialize = function() { //Never initialize UI before KMW (parameters will be undefined) - if(!keymanweb['initialized']) - { - window.setTimeout(ui.Initialize,250); return; + if(!keymanweb['initialized']) { + ui.initTimer = window.setTimeout(ui.Initialize,250); + return; + } + + if(ui.init || util['isTouchDevice']()) { + return; } - - if(ui.init || util['isTouchDevice']()) return; - + ui.init = true; - + // While the `ui.init` check above will prevent the timeout's call from + // re-evaluating _this instance_'s method, it can have nasty cross-effects + // in unit testing if not cleared, calling this modules' `Initialize` + // _on a different module_! + window.clearTimeout(ui.initTimer); + util['addStyleSheet'](ui._Appearance); - + ui._KeymanWeb_KbdList = util['createElement']('ul'); ui._KeymanWeb_KbdList.id = 'KeymanWeb_KbdList'; - + var _elem = document.getElementById('KeymanWebControl'); if(!_elem) { @@ -305,25 +313,25 @@ if(!window['keyman']['ui']['name']) { } } } - + // Insert as first child of body if not defined by user if(!_elem && (document.body != null)) { _elem=document.createElement('DIV'); - _elem.id='KeymanWebControl'; + _elem.id='KeymanWebControl'; document.body.insertBefore(_elem,document.body.firstChild); ui._insertedElem = _elem; } - - + + var imgPath=util['getOption']('resources')+'ui/button/'; if(_elem) - { + { // Append another DIV to follow the main control with clear:both to prevent selection over entire width of window var dx=document.createElement('DIV'),ds=dx.style; ds.clear='both'; _elem.parentNode.insertBefore(dx,_elem.nextSibling); - + var _btn=util['createElement']('img'), _ul=util['createElement']('ul'),_li0=util['createElement']('li'); _btn.id = 'kmwico_a'; _btn.src = imgPath+'kmw_button.gif'; @@ -339,20 +347,20 @@ if(!window['keyman']['ui']['name']) { else return; if(!keymanweb['iOS']) - { - var _li = util['createElement']('li'); + { + var _li = util['createElement']('li'); var _a = util['createElement']('a'); var _img = util['createElement']('img'); _img.src = imgPath+'kbdicon.gif'; _a.appendChild(_img); - - var _txt1 = document.createTextNode(' Hide Keyboard'); + + var _txt1 = document.createTextNode(' Hide Keyboard'); var _txt2 = document.createTextNode(' Show Keyboard'); var _sp1 = util['createElement']('span'); _sp1.id = 'KMW_KbdVisibleMsg'; _sp1.appendChild(_txt1); _a.appendChild(_sp1); - + var _sp2 = util['createElement']('span'); _sp2.id = 'KMW_KbdHiddenMsg'; _sp2.appendChild(_txt2); @@ -366,29 +374,29 @@ if(!window['keyman']['ui']['name']) { ui._KeymanWeb_KbdList.appendChild(_li); } - var _li1 = util['createElement']('li'); - _li1.id = 'KMW_ButtonUI_KbdList'; + var _li1 = util['createElement']('li'); + _li1.id = 'KMW_ButtonUI_KbdList'; var _a1 = util['createElement']('a'); _a1.appendChild(document.createTextNode('(System keyboard)')); _a1.onclick = ui._SelectKeyboard; - _a1.href = '#'; + _a1.href = '#'; _a1.id='KMWSel_$'; _a1.className='selected'; _li1.appendChild(_a1); ui._KMWSel = _a1; ui._KeymanWeb_KbdList.appendChild(_li1); - var _kbds = keymanweb['getKeyboards'](), _added = []; + var _kbds = keymanweb['getKeyboards'](), _added = []; ui.updateKeyboardList(); - + document.getElementById('kmwico_li').appendChild(ui._KeymanWeb_KbdList); var _sfEl = document.getElementById("kmwico_li"); util['attachDOMEvent'](_sfEl,'mousedown',ui._SelectorMouseDown); util['attachDOMEvent'](_sfEl,'mouseover',ui._SelectorMouseOver); - util['attachDOMEvent'](_sfEl,'mouseout',ui._SelectorMouseOut); + util['attachDOMEvent'](_sfEl,'mouseout',ui._SelectorMouseOut); util['attachDOMEvent'](_sfEl,'mouseup',ui._SelectorMouseUp); ui.registerEvents(); @@ -404,108 +412,108 @@ if(!window['keyman']['ui']['name']) { /** * Keyboard registration event handler - * - * Set a timer to update the UI keyboard list on timeout after each keyboard is registered, + * + * Set a timer to update the UI keyboard list on timeout after each keyboard is registered, * thus updating only once when only if multiple keyboards are registered together - */ - keymanweb['addEventListener']('keyboardregistered', + */ + keymanweb['addEventListener']('keyboardregistered', function(p) - { + { ui.updateList = true; if(ui.updateTimer) clearTimeout(ui.updateTimer); ui.updateTimer = setTimeout(ui.updateKeyboardList,20); - }); + }); /** * Update the entire menu when keyboards are registered or deregistered - **/ + **/ ui.updateKeyboardList = function() - { + { ui.updateList = false; - + if(!ui.init) return; - + // Clear existing list first (first two nodes must be preserved) for(var i:number=ui._KeymanWeb_KbdList.childNodes.length; i>2; i--) ui._KeymanWeb_KbdList.removeChild(ui._KeymanWeb_KbdList.childNodes[i-1]); - + var kbds=keymanweb['getKeyboards'](); if(kbds.length > 0) { for(var i:number=0; i 26) _t=_t.substr(0,24)+'\u2026'; - _a2.appendChild(document.createTextNode(_t)); + _a2.appendChild(document.createTextNode(_t)); _a2.onclick = ui._SelectKeyboard; _a2.href = '#'; _a2.id='KMWSel_'+Lki+'$'+Lklc; _li2.appendChild(_a2); ui._KeymanWeb_KbdList.appendChild(_li2); } - + // Define appearance of this interface - ui._Appearance = + ui._Appearance = "#kmwico, #kmwkbd {"+ "vertical-align: middle;"+ "} "+ "#KeymanWebControl {float:left;} "+ - + "#KeymanWebControl * "+ "{"+ "letter-spacing: 0px !important;"+ "line-height: 1li !important;"+ "white-space: nowrap !important;"+ "} "+ - + "#KeymanWebControl #kmwico img {"+ "vertical-align: top;"+ "padding: 0;"+ "margin: 0;"+ "border: none;"+ "} "+ - + "#KeymanWebControl #kmwico, #kmwico ul {"+ "padding: 0;"+ "margin: 0;"+ "list-style: none;"+ "} "+ - + "#KeymanWebControl #kmwico_a {"+ "display: block;"+ //"border: none !important;"+ "width: 22px; height: 23px; "+ /* sizes needed for kmw_button.gif */ "} "+ - + "#KeymanWebControl #kmwico li { "+ "text-align: left;"+ "} "+ - + "#KeymanWebControl #kmwico li ul {"+ "display: block;"+ "position: absolute;"+ @@ -516,27 +524,27 @@ if(!window['keyman']['ui']['name']) { "box-shadow: 4px 4px 2px #666;"+ "z-index: 10011;"+ /* above the osk */ "} "+ - + "#KeymanWebControl #kmwico li.sfunhover ul {"+ "display: none; left: -5999px;"+ "} "+ - + "#KeymanWebControl #kmwico li:hover ul, #kmwico li.sfhover ul {"+ "display: block;"+ "left: auto;"+ "} "+ - + "#KeymanWebControl #kmwico ul li {"+ "float: none;"+ "padding: 0 !important;"+ "margin: 0 !important;"+ "width: 136px !important;"+ "} "+ - + "#KeymanWebControl #KMW_LanguageName {"+ "font-weight: bold;"+ "} "+ - + "#KeymanWebControl #kmwico ul li a, #kmwico ul li a:visited {"+ "display: block;"+ "padding: 2px 4px !important;"+ @@ -547,17 +555,17 @@ if(!window['keyman']['ui']['name']) { "font-size: 8pt;"+ "text-decoration: none;"+ "} "+ - + "#KeymanWebControl #kmwico ul li a.selected {"+ "font-weight: bold;"+ "color: black;"+ "} "+ - + "#KeymanWebControl #kmwico ul li a:hover {"+ "color: white;"+ "background-color: #ad4a28;"+ "} "+ - + "#KeymanWebControl #kmwico ul li a.kmw_disabled, #KeymanWebControl #kmwico ul li a.kmw_disabled:hover {"+ "color: #c0c0c0; cursor: default;"+ "background-color: white;"+ @@ -581,13 +589,9 @@ if(!window['keyman']['ui']['name']) { "#KeymanWebControl #kmwico ul li#KMW_ButtonUI_KbdIcon {"+ "border-bottom: solid 1px #ad4a28;"+ - "} "; + "} "; - // Initialize after KMW is fully initialized, if UI already loaded - keymanweb['addEventListener']('loaduserinterface',ui.Initialize); - // but also call initialization when script loaded, which is after KMW initialization for asynchronous script loading ui.Initialize(); - } catch(err){} } \ No newline at end of file diff --git a/web/source/kmwuifloat.ts b/web/source/kmwuifloat.ts index 2367fbe61be..2cf5f75f662 100644 --- a/web/source/kmwuifloat.ts +++ b/web/source/kmwuifloat.ts @@ -48,6 +48,7 @@ if(!window['keyman']['ui']['name']) { ui.updateTimer = null; // prevent unnecessary list refreshing ui.floatRight = false; // align left by default ui.initialized = false; // initialization flag + ui.initTimer = null; /** * Display or hide the OSK from the OSK icon link @@ -74,12 +75,16 @@ if(!window['keyman']['ui']['name']) { ui['initialize'] = ui.Initialize = function() { // Must always initialize after keymanWeb itself, otherwise options are undefined - if(!keymanweb['initialized']) - { - window.setTimeout(ui.Initialize,50); return; + if(!keymanweb['initialized']) { + ui.initTimer = window.setTimeout(ui.Initialize,50); + return; + } + + if(ui.initialized || util['isTouchDevice']()) { + return; } - if(ui.initialized || util['isTouchDevice']()) return; + window.clearTimeout(ui.initTimer); var imgPath=util['getOption']('resources')+"ui/float/"; @@ -541,9 +546,6 @@ if(!window['keyman']['ui']['name']) { if(window.addEventListener) window.addEventListener('resize', ui._Resize, false); - // Initialize after KMW is fully initialized, if UI already loaded - keymanweb['addEventListener']('loaduserinterface',ui.Initialize); - // but also call initialization when script loaded, which is after KMW initialization for asynchronous script loading ui.Initialize(); From fd713e03630624077d24652f748ce5cc09ae4885 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 5 Aug 2022 13:31:05 +0700 Subject: [PATCH 05/31] fix(web): late toolbar init --- web/source/kmwuitoolbar.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/web/source/kmwuitoolbar.ts b/web/source/kmwuitoolbar.ts index 8d603cd5f15..0bfc00d0299 100644 --- a/web/source/kmwuitoolbar.ts +++ b/web/source/kmwuitoolbar.ts @@ -1215,9 +1215,8 @@ if(!window['keyman']['ui']['name']) { } // Initialize when everything defined (replaces unreliable onload event handler) - // ui.initToolbarUI(); - // No, initialization must not be done before KMW is ready! - // ui.initialize() is now called by keymanweb when document is ready and kmw initialization completed - + // In case the toolbar script loads a bit later than the main KMW script + // (may happen in unit testing) + ui.initToolbarUI(); // equivalent to ui.Initialize() from the other UI modules } catch(ex){} } \ No newline at end of file From 365721937410a7ecb2874f905b2f3ae140799c5d Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 5 Aug 2022 17:31:48 +0200 Subject: [PATCH 06/31] chore(linux): Update debian changelog (cherry picked from commit cbb9e6537d340495b5186cf498c1d767876ffc00) --- linux/debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/linux/debian/changelog b/linux/debian/changelog index b21640c5c7e..6990b7dbecc 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,3 +1,10 @@ +keyman (15.0.268-1) unstable; urgency=medium + + * New upstream release. + * Re-release to Debian + + -- Eberhard Beilharz Fri, 05 Aug 2022 17:31:36 +0200 + keyman (15.0.267-1) unstable; urgency=medium * New upstream release. From b1d201a3d73af4d8467f095c418dbf30aebc411a Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 8 Aug 2022 16:38:35 +0200 Subject: [PATCH 07/31] feat(linux): Replace deprecated distutils Fixes #6955 --- .../keyman_config/install_kmp.py | 4 +-- .../keyman_config/install_window.py | 6 ++-- linux/keyman-config/km-package-install | 6 ++-- .../keyman-config/tests/test_uninstall_kmp.py | 36 +++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/linux/keyman-config/keyman_config/install_kmp.py b/linux/keyman-config/keyman_config/install_kmp.py index 17c40e117bb..bed23e3f418 100755 --- a/linux/keyman-config/keyman_config/install_kmp.py +++ b/linux/keyman-config/keyman_config/install_kmp.py @@ -4,7 +4,7 @@ import logging import os import zipfile -from distutils.version import StrictVersion +from pkg_resources import parse_version from enum import Enum from shutil import rmtree @@ -127,7 +127,7 @@ def _install_kmp(self, inputfile, online, language, area): fileVersion = secure_lookup(system, 'fileVersion') if not fileVersion: fileVersion = '7.0' - if StrictVersion(fileVersion) > StrictVersion(__version__): + if parse_version(fileVersion) > parse_version(__version__): logging.error("install_kmp.py: error: %s requires a newer version of Keyman (%s)", inputfile, fileVersion) rmtree(self.packageDir) diff --git a/linux/keyman-config/keyman_config/install_window.py b/linux/keyman-config/keyman_config/install_window.py index d0ed6c70baa..faa64f103d9 100755 --- a/linux/keyman-config/keyman_config/install_window.py +++ b/linux/keyman-config/keyman_config/install_window.py @@ -15,7 +15,7 @@ gi.require_version('Gtk', '3.0') gi.require_version('WebKit2', '4.0') -from distutils.version import StrictVersion +from pkg_resources import parse_version from gi.repository import Gtk, WebKit2 @@ -107,8 +107,8 @@ def __init__(self, kmpfile, online=False, viewkmp=None, language=None): try: logging.info("package version %s", secure_lookup(info, 'version', 'description')) logging.info("installed kmp version %s", installed_kmp_ver) - if StrictVersion(secure_lookup(info, 'version', - 'description')) <= StrictVersion(installed_kmp_ver): + if parse_version(secure_lookup(info, 'version', + 'description')) <= parse_version(installed_kmp_ver): dialog = Gtk.MessageDialog( viewkmp, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Keyboard is installed already")) diff --git a/linux/keyman-config/km-package-install b/linux/keyman-config/km-package-install index b1fbb36c809..ec4042faf3c 100755 --- a/linux/keyman-config/km-package-install +++ b/linux/keyman-config/km-package-install @@ -6,7 +6,7 @@ import logging import os import sys import time -from distutils.version import StrictVersion +from pkg_resources import parse_version from zipfile import is_zipfile from keyman_config import KeymanApiUrl, __version__, secure_lookup @@ -150,8 +150,8 @@ def main(): sys.exit(3) kbdata_v = secure_lookup(kbdata, 'version') if installed_kmp_v and kbdata_v: - kbdata_version = StrictVersion(kbdata_v) - installed_kmp_ver = StrictVersion(installed_kmp_v) + kbdata_version = parse_version(kbdata_v) + installed_kmp_ver = parse_version(installed_kmp_v) if kbdata_version == installed_kmp_ver: print("km-package-install: Version %s of the %s keyboard package is already installed." % (installed_kmp_ver, args.package)) diff --git a/linux/keyman-config/tests/test_uninstall_kmp.py b/linux/keyman-config/tests/test_uninstall_kmp.py index c8277d59605..a6e2aa301b1 100644 --- a/linux/keyman-config/tests/test_uninstall_kmp.py +++ b/linux/keyman-config/tests/test_uninstall_kmp.py @@ -25,40 +25,40 @@ def test_UninstallKeyboardsFromGnome_RemoveNonExistingKeyboard(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('ibus', 'fooDir/foo2.kmx')] + ('ibus', 'fooDir/foo2.kmx')] # Execute uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with([ - ('ibus', 'fooDir/foo2.kmx')]) + ('ibus', 'fooDir/foo2.kmx')]) def test_UninstallKeyboardsFromGnome_RemoveOneKeyboard(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx')] + ('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx')] # Execute uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( - [('xkb', 'en')]) + [('xkb', 'en')]) def test_UninstallKeyboardsFromGnome_RemoveMultipleKeyboards(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')] + ('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')] # Execute uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( - [('xkb', 'en')]) + [('xkb', 'en')]) def test_UninstallKeyboardsFromGnome_RemoveAllKeyboards(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')] + ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')] # Execute uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir') # Verify @@ -68,45 +68,45 @@ def test_UninstallKeyboardsFromGnome_RemoveKeyboard_SingleLanguage(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')] + ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')] # Execute uninstall_keyboards_from_gnome([{'id': 'foo1', 'languages': [{'id': 'en'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( - [('xkb', 'en')]) + [('xkb', 'en')]) def test_UninstallKeyboardsFromGnome_RemoveKeyboard_MultipleLanguages(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('xkb', 'en'), ('ibus', 'fr:fooDir/foo1.kmx')] + ('xkb', 'en'), ('ibus', 'fr:fooDir/foo1.kmx')] # Execute uninstall_keyboards_from_gnome( - [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}], 'fooDir') + [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( - [('xkb', 'en')]) + [('xkb', 'en')]) def test_UninstallKeyboardsFromGnome_RemoveKeyboard_OneNotMatchingLanguage(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')] + ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')] # Execute uninstall_keyboards_from_gnome( - [{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir') + [{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( - [('xkb', 'en')]) + [('xkb', 'en')]) def test_UninstallKeyboardsFromGnome_RemoveKeyboard_RemovesAllMatching(self): # Setup mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ - ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx'), ('ibus', 'fr:fooDir/foo1.kmx')] + ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx'), ('ibus', 'fr:fooDir/foo1.kmx')] # Execute uninstall_keyboards_from_gnome( - [{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir') + [{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( - [('xkb', 'en')]) + [('xkb', 'en')]) From a2cf9396830ab2b82b6bac3f4089ba5cb0e881a9 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 8 Aug 2022 14:01:36 -0400 Subject: [PATCH 08/31] auto: increment master version to 16.0.45 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 7d110e920d2..f0e5b0f9903 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 16.0.44 alpha 2022-08-08 + +* chore(linux): Update debian changelog (#7041) + ## 16.0.43 alpha 2022-08-05 * chore(web): centralizes web-based modules' CI unit test configurations (#7024) diff --git a/VERSION.md b/VERSION.md index c99e566a459..7ed92d3ac35 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -16.0.44 \ No newline at end of file +16.0.45 \ No newline at end of file From dbca5712e71e7c48a9e40d87cd36ccec2591e23b Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 9 Aug 2022 12:08:42 +0200 Subject: [PATCH 09/31] chore(linux): Adjust Linux source package to restructured code --- linux/scripts/dist.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/linux/scripts/dist.sh b/linux/scripts/dist.sh index e0d876a5081..5398932d661 100755 --- a/linux/scripts/dist.sh +++ b/linux/scripts/dist.sh @@ -68,9 +68,7 @@ for proj in ${extra_projects}; do dpkg-source --tar-ignore=*~ --tar-ignore=.git --tar-ignore=.gitattributes \ --tar-ignore=.gitignore --tar-ignore=experiments --tar-ignore=debian \ --tar-ignore=.github --tar-ignore=.vscode --tar-ignore=android \ - --tar-ignore=common/lexical-model-types \ - --tar-ignore=common/models --tar-ignore=common/predictive-text \ - --tar-ignore=common/test --tar-ignore=developer --tar-ignore=docs --tar-ignore=ios \ + --tar-ignore=common --tar-ignore=developer --tar-ignore=docs --tar-ignore=ios \ --tar-ignore=linux/keyman-config/buildtools/build-langtags.py --tar-ignore=__pycache__ \ --tar-ignore=linux/help --tar-ignore=linux/Jenkinsfile \ --tar-ignore=linux/keyboardprocessor --tar-ignore=linux/legacy \ From 03397be1536ea441b2135a46a1b9c4809ee6c77a Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 9 Aug 2022 14:09:40 -0400 Subject: [PATCH 10/31] auto: increment master version to 16.0.46 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f0e5b0f9903..58aeca1081a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 16.0.45 alpha 2022-08-09 + +* feat(linux): Replace deprecated distutils (#7051) +* chore(linux): Adjust Linux source package to restructured code (#7056) + ## 16.0.44 alpha 2022-08-08 * chore(linux): Update debian changelog (#7041) diff --git a/VERSION.md b/VERSION.md index 7ed92d3ac35..8018df015ce 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -16.0.45 \ No newline at end of file +16.0.46 \ No newline at end of file From 422e7227a6b508a8a8e80db1d59e7b07cd3ef7ee Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 11:30:47 +0200 Subject: [PATCH 11/31] chore(core): move kmx_file.h to common --- {core/src/kmx => common/include}/kmx_file.h | 7 ++++++- core/meson.build | 4 ++++ core/src/meson.build | 4 ++-- core/tests/unit/kmnkbd/meson.build | 2 +- core/tests/unit/kmnkbd/test_kmx_xstring.cpp | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) rename {core/src/kmx => common/include}/kmx_file.h (98%) diff --git a/core/src/kmx/kmx_file.h b/common/include/kmx_file.h similarity index 98% rename from core/src/kmx/kmx_file.h rename to common/include/kmx_file.h index bc32a4acc27..91df31c3b22 100644 --- a/core/src/kmx/kmx_file.h +++ b/common/include/kmx_file.h @@ -5,11 +5,14 @@ #pragma once -#include "kmx_base.h" +#include +#ifdef KMN_KBP +// TODO: move this to a common namespace keyman::common::kmx_file or similar in the future namespace km { namespace kbp { namespace kmx { +#endif /* */ @@ -352,6 +355,8 @@ static_assert(sizeof(COMP_KEY) == KEYBOARDFILEKEY_SIZE, "COMP_KEY must be KEYBOA static_assert(sizeof(COMP_GROUP) == KEYBOARDFILEGROUP_SIZE, "COMP_GROUP must be KEYBOARDFILEGROUP_SIZE bytes"); static_assert(sizeof(COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOARD must be KEYBOARDFILEHEADER_SIZE bytes"); +#ifdef KMN_KBP } // namespace kmx } // namespace kbp } // namespace km +#endif \ No newline at end of file diff --git a/core/meson.build b/core/meson.build index ed5e33bdbbf..cad35decec2 100644 --- a/core/meson.build +++ b/core/meson.build @@ -37,6 +37,10 @@ message('compiler.get_id(): ' + compiler.get_id()) cc = meson.get_compiler('c') +# TODO: Shared includes may use namespaces, etc which need future tidyup. +# For now, we use KMN_KBP to inject the km::kbp::kmx namespace +defns = ['-DKMN_KBP'] + subdir('doc') subdir('include') subdir('src') diff --git a/core/src/meson.build b/core/src/meson.build index 1e3b6e82fcd..ebca69b5991 100644 --- a/core/src/meson.build +++ b/core/src/meson.build @@ -4,7 +4,7 @@ # Authors: Tim Eves (TSE) # -defns = ['-DKMN_KBP_EXPORTING'] +defns += ['-DKMN_KBP_EXPORTING'] version_res = [] if compiler.get_id() == 'gcc' or compiler.get_id() == 'clang' @@ -54,7 +54,7 @@ endif if compiler.get_id() == 'emscripten' warns = [] flags = [] - defns = [] + defns = ['-DKMN_KBP'] links = [] endif diff --git a/core/tests/unit/kmnkbd/meson.build b/core/tests/unit/kmnkbd/meson.build index 2a794ec1cbd..4cdaa91186e 100644 --- a/core/tests/unit/kmnkbd/meson.build +++ b/core/tests/unit/kmnkbd/meson.build @@ -13,7 +13,7 @@ else warns = [] endif -defns=['-DKMN_KBP_STATIC'] +defns+=['-DKMN_KBP_STATIC'] tests = [ ['context-api', 'context_api.cpp'], ['keyboard-api', 'keyboard_api.cpp'], diff --git a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp index 3b944028c34..eec1894c0ad 100644 --- a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp +++ b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp @@ -11,7 +11,7 @@ #include #include #include "../../../src/kmx/kmx_xstring.h" -#include "../../../src/kmx/kmx_file.h" +#include #include "../test_assert.h" using namespace km::kbp::kmx; From bb24d59b5eaed4e066033d576d339980e4488560 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 11:15:56 +0200 Subject: [PATCH 12/31] chore(core): remove duplicate types --- core/include/keyman/keyboardprocessor.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/include/keyman/keyboardprocessor.h b/core/include/keyman/keyboardprocessor.h index 3e683d06954..134f1c89477 100644 --- a/core/include/keyman/keyboardprocessor.h +++ b/core/include/keyman/keyboardprocessor.h @@ -110,13 +110,6 @@ extern "C" #endif // Basic types // -#if defined(__cplusplus) -typedef char16_t km_kbp_cp; -typedef char32_t km_kbp_usv; -#else -typedef uint16_t km_kbp_cp; // code point -typedef uint32_t km_kbp_usv; // Unicode Scalar Value -#endif typedef uint16_t km_kbp_virtual_key; // A virtual key code. typedef uint32_t km_kbp_status; // Status return code. From dedb06e7cc7450c5bca255fda8cbed5beac1ab30 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 11:13:00 +0200 Subject: [PATCH 13/31] chore(common): refactor shared types into km_types.h --- common/include/km_types.h | 65 ++++++++++++++++++++ core/include/keyman/keyboardprocessor_bits.h | 2 + core/include/meson.build | 2 +- core/src/kmx/kmx_base.h | 35 ----------- 4 files changed, 68 insertions(+), 36 deletions(-) create mode 100644 common/include/km_types.h diff --git a/common/include/km_types.h b/common/include/km_types.h new file mode 100644 index 00000000000..5cc7257d235 --- /dev/null +++ b/common/include/km_types.h @@ -0,0 +1,65 @@ +#pragma once + +/* +#if defined(_WIN32) || defined(_WIN64) +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#endif +*/ + +#if defined(__LP64__) || defined(_LP64) +/* 64-bit, g++ */ +#define KMX_64BIT +#endif + +#if defined(_WIN64) && !defined(USE_64) +/* 64-bit, Windows */ +#define KMX_64BIT +#endif + +typedef uint32_t KMX_DWORD; +typedef int32_t KMX_BOOL; +typedef uint8_t KMX_BYTE; +typedef uint16_t KMX_WORD; + +#if defined(__cplusplus) +typedef char16_t km_kbp_cp; +typedef char32_t km_kbp_usv; +#else +typedef uint16_t km_kbp_cp; // code point +typedef uint32_t km_kbp_usv; // Unicode Scalar Value +#endif + +typedef km_kbp_cp KMX_WCHAR; // wc, 16-bit UNICODE character +typedef KMX_WCHAR *PKMX_WCHAR; + +typedef char KMX_CHAR; +typedef KMX_CHAR *PKMX_CHAR; + +typedef uint32_t KMX_UINT; + +typedef KMX_BYTE *PKMX_BYTE; +typedef KMX_WORD *PKMX_WORD; +typedef KMX_DWORD *PKMX_DWORD; + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +// Macros and types to support char16_t vs wchar_t depending on project + +#ifdef USE_CHAR16_T +#define lpuch(x) u ## x +typedef char16_t KMX_UCHAR; +#else +#define lpuch(x) L ## x +typedef wchar_t KMX_UCHAR; +#endif + +typedef KMX_UCHAR* KMX_PUCHAR; diff --git a/core/include/keyman/keyboardprocessor_bits.h b/core/include/keyman/keyboardprocessor_bits.h index d844d4e2a69..537b943aec3 100644 --- a/core/include/keyman/keyboardprocessor_bits.h +++ b/core/include/keyman/keyboardprocessor_bits.h @@ -58,3 +58,5 @@ #define KMN_API _kmn_tag_fn(_kmn_import_flag) #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_import_flag) #endif + +#include diff --git a/core/include/meson.build b/core/include/meson.build index b6211db0f22..f52ab00d5cf 100644 --- a/core/include/meson.build +++ b/core/include/meson.build @@ -6,5 +6,5 @@ # History: 6 Oct 2018 - TSE - Move into keyman folder. # -inc = include_directories('.', is_system: true) +inc = include_directories('.', '../../common/include', is_system: true) subdir('keyman') diff --git a/core/src/kmx/kmx_base.h b/core/src/kmx/kmx_base.h index ce3a1465cd4..562998472ca 100644 --- a/core/src/kmx/kmx_base.h +++ b/core/src/kmx/kmx_base.h @@ -10,41 +10,6 @@ #define strncasecmp _strnicmp #endif -#if defined(__LP64__) || defined(_LP64) -/* 64-bit, g++ */ -#define KMX_64BIT -#endif - -#if defined(_WIN64) && !defined(USE_64) -/* 64-bit, Windows */ -#define KMX_64BIT -#endif - -typedef uint32_t KMX_DWORD; -typedef int32_t KMX_BOOL; -typedef uint8_t KMX_BYTE; -typedef uint16_t KMX_WORD; - -typedef km_kbp_cp KMX_WCHAR; // wc, 16-bit UNICODE character -typedef KMX_WCHAR *PKMX_WCHAR; - -typedef char KMX_CHAR; -typedef KMX_CHAR *PKMX_CHAR; - -typedef uint32_t KMX_UINT; - -typedef KMX_BYTE *PKMX_BYTE; -typedef KMX_WORD *PKMX_WORD; -typedef KMX_DWORD *PKMX_DWORD; - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - namespace km { namespace kbp { namespace kmx { From 16082ff2ae27e005d1f1d15128b01d10cf6ee7c9 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 11 Aug 2022 09:56:46 +0200 Subject: [PATCH 14/31] chore(linux): Refactor `jenkins.sh` - use standard Keyman include scripts - remove package build support for legacy projects - install dependencies from `debian/control` file instead of maintaining a separate list --- linux/scripts/jenkins.sh | 72 +++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/linux/scripts/jenkins.sh b/linux/scripts/jenkins.sh index 4fe776c40f7..c7406d88314 100755 --- a/linux/scripts/jenkins.sh +++ b/linux/scripts/jenkins.sh @@ -1,16 +1,19 @@ -#!/bin/bash -e +#!/bin/bash # $1 - project name with appended tier, e.g. ibus-kmfl-alpha # $2 - GPG key used for signing the source package -PROGRAM_NAME="$(basename "$0")" +set -e +set -u -. $HOME/ci-builder-scripts/bash/common.sh -init --no-package +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null || readlink -f "${BASH_SOURCE[0]}")" +. "$(dirname "$THIS_SCRIPT")/../../resources/build/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" keyman_projects="keyman" -if [ -n "$BUILD_LEGACY" ]; then - keyman_projects="keyman kmflcomp libkmfl ibus-kmfl" -fi tier="stable" @@ -24,72 +27,59 @@ proj="$1" proj=${proj%"-alpha"} proj=${proj%"-beta"} -if [ "$proj" == "keyman" ]; then - fullsourcename="keyman" - sourcedir="$KEYMAN_ROOT" -else - # check if project is known - if [[ $keyman_projects =~ (^|[[:space:]])$proj($|[[:space:]]) ]]; then - fullsourcename="$1" - sourcedir="legacy/$proj" - else - stderr "$proj not in known projects ($keyman_projects)" - exit -1 - fi -fi +fullsourcename="keyman" +sourcedir="$KEYMAN_ROOT" sourcename=${fullsourcename%"-alpha"} sourcename=${sourcename%"-beta"} +# set Debian/changelog environment +export DEBFULLNAME="${fullsourcename} Package Signing Key" +export DEBEMAIL='jenkins@sil.org' + checkAndInstallRequirements() { - local TOINSTALL + local TOINSTALL="" - for p in dh-python gir1.2-webkit2-4.0 python3-all python3-setuptools \ - python3-requests python3-requests-cache python3-numpy python3-pil python3-lxml \ - python3-gi python3-magic python3-qrcode cargo build-essential python3-dbus + for p in devscripts equivs do - if ! dpkg -l | grep -q $p; then + if ! dpkg -s $p >/dev/null 2>&1; then TOINSTALL="$TOINSTALL $p" fi done - if [ ! -f /usr/bin/perl ]; then - TOINSTALL="$TOINSTALL perl" - fi - - if [ ! -f /usr/bin/meson ]; then - TOINSTALL="$TOINSTALL meson" - fi + export DEBIAN_FRONTEND=noninteractive if [ -n "$TOINSTALL" ]; then - log "Installing prerequisites:$TOINSTALL" sudo apt-get update sudo apt-get -qy install $TOINSTALL fi + + sudo mk-build-deps debian/control + sudo apt-get -qy install ./keyman-build-deps_*.deb + sudo rm -f keyman-buid-deps_* } checkAndInstallRequirements # clean up prev deb builds -log "cleaning previous builds of $1" - +echo_heading "cleaning previous builds of $1" rm -rf builddebs rm -rf $sourcedir/${1}_*.{dsc,build,buildinfo,changes,tar.?z,log} rm -rf $sourcedir/../${1}_*.{dsc,build,buildinfo,changes,tar.?z,log} -log "Make source package for $fullsourcename" -log "reconfigure" +echo_heading "Make source package for $fullsourcename" +echo_heading "reconfigure" JENKINS="yes" TIER="$tier" ./scripts/reconf.sh $sourcename -log "Make origdist" +echo_heading "Make origdist" ./scripts/dist.sh origdist $sourcename -log "Make deb source" +echo_heading "Make deb source" ./scripts/deb.sh sourcepackage $proj #sign source package -for file in `ls builddebs/*.dsc`; do - log "Signing source package $file" +for file in $(ls builddebs/*.dsc); do + echo_heading "Signing source package $file" debsign -k$2 $file done From 600f6bfec4e87df2aeb9a01c71e157bd604c4289 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 13:18:28 +0200 Subject: [PATCH 15/31] chore(linux): update include paths --- docs/settings/linux/c_cpp_properties.json | 2 +- docs/settings/linux/tasks.json | 2 +- linux/debian/rules | 2 +- linux/ibus-keyman/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/settings/linux/c_cpp_properties.json b/docs/settings/linux/c_cpp_properties.json index f6b6a18a49d..ce69ca56e3a 100644 --- a/docs/settings/linux/c_cpp_properties.json +++ b/docs/settings/linux/c_cpp_properties.json @@ -2,7 +2,7 @@ "configurations": [ { "name": "linux", - "includePath": ["${workspaceFolder}/core/include/**"], + "includePath": ["${workspaceFolder}/core/include/**", "${workspaceFolder}/common/include/**"], "defines": [], "compilerPath": "/usr/lib/ccache/clang", "cStandard": "c11", diff --git a/docs/settings/linux/tasks.json b/docs/settings/linux/tasks.json index 51fe4d34eae..7beff2efe8e 100644 --- a/docs/settings/linux/tasks.json +++ b/docs/settings/linux/tasks.json @@ -66,7 +66,7 @@ "label": "ibus-keyman: configure", "command": "./configure", "args": [ - "CPPFLAGS=\"-DG_MESSAGES_DEBUG -I${workspaceFolder}/core/build/arch/debug/include/ -I${workspaceFolder}/core/include/\"", + "CPPFLAGS=\"-DG_MESSAGES_DEBUG -I${workspaceFolder}/core/build/arch/debug/include/ -I${workspaceFolder}/common/include/ -I${workspaceFolder}/core/include/\"", "CFLAGS=\"-g -O0\"", "CXXFLAGS=\"-g -O0\"", "KEYMAN_PROC_LIBS=\"-L${workspaceFolder}/common/core/desktop/build/arch/debug/src -lkmnkbp0\"", diff --git a/linux/debian/rules b/linux/debian/rules index 87c36e453dc..5e2f0a86855 100755 --- a/linux/debian/rules +++ b/linux/debian/rules @@ -26,7 +26,7 @@ override_dh_auto_configure: # ibus-keyman cd linux/ibus-keyman && \ cp -f ../../VERSION.md VERSION && \ - export KEYMAN_PROC_CFLAGS="-I$(CURDIR)/core/build/arch/release/include -I$(CURDIR)/core/include" && \ + export KEYMAN_PROC_CFLAGS="-I$(CURDIR)/core/build/arch/release/include -I$(CURDIR)/common/include -I$(CURDIR)/core/include" && \ export KEYMAN_PROC_LIBS="-L$(CURDIR)/core/build/arch/release/src -lkmnkbp0" && \ export PKG_CONFIG_PATH=$(CURDIR)/core/build/arch/release/meson-private && \ ./autogen.sh && \ diff --git a/linux/ibus-keyman/README.md b/linux/ibus-keyman/README.md index 4f615d554fc..b22ccc3429f 100644 --- a/linux/ibus-keyman/README.md +++ b/linux/ibus-keyman/README.md @@ -24,6 +24,6 @@ For a debug build: To use the header files from the source repo, you need to specify paths to the include files in core: ```bash -./configure CPPFLAGS="-DG_MESSAGES_DEBUG -I../../core/build/arch/debug/include/ -I../../core/include/" \ +./configure CPPFLAGS="-DG_MESSAGES_DEBUG -I../../core/build/arch/debug/include/ -I../../common/include/ -I../../core/include/" \ CFLAGS="-g -O0" CXXFLAGS="-g -O0" ``` From b1b097b659e1a6e92d64fb99d3efb55663b893b2 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 14:30:15 +0200 Subject: [PATCH 16/31] chore(windows): update include paths --- windows/src/engine/keyman32/Keyman32.vcxproj | 4 ++-- windows/src/engine/keyman64/keyman64.vcxproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/windows/src/engine/keyman32/Keyman32.vcxproj b/windows/src/engine/keyman32/Keyman32.vcxproj index cb9208cd6fe..a488b1bc3ba 100644 --- a/windows/src/engine/keyman32/Keyman32.vcxproj +++ b/windows/src/engine/keyman32/Keyman32.vcxproj @@ -55,11 +55,11 @@ $(ProjectDir)..\..\..\..\core\build\x86\$(Configuration)\src;$(ProjectDir)..\..\..\..\core\build\rust\x86\$(Configuration);$(LibraryPath) - $(ProjectDir)..\..\..\..\core\include;$(ProjectDir)..\..\..\..\core\build\x86\$(Configuration)\include;$(IncludePath) + $(ProjectDir)..\..\..\..\common\include;$(ProjectDir)..\..\..\..\core\include;$(ProjectDir)..\..\..\..\core\build\x86\$(Configuration)\include;$(IncludePath) $(ProjectDir)..\..\..\..\core\build\x86\$(Configuration)\src;$(ProjectDir)..\..\..\..\core\build\rust\x86\$(Configuration);$(LibraryPath) - $(ProjectDir)..\..\..\..\core\build\x86\$(Configuration)\include;$(ProjectDir)..\..\..\..\core\include;$(IncludePath) + $(ProjectDir)..\..\..\..\common\include;$(ProjectDir)..\..\..\..\core\include;$(ProjectDir)..\..\..\..\core\build\x86\$(Configuration)\include;$(IncludePath) diff --git a/windows/src/engine/keyman64/keyman64.vcxproj b/windows/src/engine/keyman64/keyman64.vcxproj index 5f27accaccb..49725bc50a7 100644 --- a/windows/src/engine/keyman64/keyman64.vcxproj +++ b/windows/src/engine/keyman64/keyman64.vcxproj @@ -55,11 +55,11 @@ $(ProjectDir)..\..\..\..\core\build\x64\$(Configuration)\src;$(ProjectDir)..\..\..\..\core\build\rust\x64\$(Configuration);$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) - $(ProjectDir)..\..\..\..\core\build\x64\$(Configuration)\include;$(ProjectDir)..\..\..\..\core\include;$(IncludePath) + $(ProjectDir)..\..\..\..\common\include;$(ProjectDir)..\..\..\..\core\build\x64\$(Configuration)\include;$(ProjectDir)..\..\..\..\core\include;$(IncludePath) $(ProjectDir)..\..\..\..\core\build\x64\$(Configuration)\src;$(ProjectDir)..\..\..\..\core\build\rust\x64\$(Configuration);$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) - $(ProjectDir)..\..\..\..\core\build\x64\$(Configuration)\include;$(ProjectDir)..\..\..\..\core\include;$(IncludePath) + $(ProjectDir)..\..\..\..\common\include;$(ProjectDir)..\..\..\..\core\build\x64\$(Configuration)\include;$(ProjectDir)..\..\..\..\core\include;$(IncludePath) From e30871f01e38aa67a58000f5c9c5ece88b5e4dd9 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 14:56:46 +0200 Subject: [PATCH 17/31] chore(linux): add common/include to further paths --- common/web/keyboard-processor/src/text/codes.ts | 2 +- common/windows/cpp/include/legacy_kmx_file.h | 2 +- docs/settings/linux/c_cpp_properties.json | 2 +- linux/ibus-keyman/tests/Makefile.am | 2 +- linux/scripts/build.sh | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/web/keyboard-processor/src/text/codes.ts b/common/web/keyboard-processor/src/text/codes.ts index 0ea17a07fc3..915ae7feed9 100644 --- a/common/web/keyboard-processor/src/text/codes.ts +++ b/common/web/keyboard-processor/src/text/codes.ts @@ -1,7 +1,7 @@ namespace com.keyman.text { export var Codes = { // Define Keyman Developer modifier bit-flags (exposed for use by other modules) - // Compare against /core/src/kmx/kmx_file.h. CTRL+F "#define LCTRLFLAG" to find the secton. + // Compare against /common/include/kmx_file.h. CTRL+F "#define LCTRLFLAG" to find the secton. modifierCodes: { "LCTRL":0x0001, // LCTRLFLAG "RCTRL":0x0002, // RCTRLFLAG diff --git a/common/windows/cpp/include/legacy_kmx_file.h b/common/windows/cpp/include/legacy_kmx_file.h index 7aa1ada5834..8e121be13f7 100644 --- a/common/windows/cpp/include/legacy_kmx_file.h +++ b/common/windows/cpp/include/legacy_kmx_file.h @@ -2,7 +2,7 @@ Name: legacy_kmx_file Copyright: Copyright (C) SIL International. Documentation: - Description: Describes .kmx binary format. To be replaced with Core's kmx_file.h + Description: Describes .kmx binary format. To be replaced with common/include/kmx_file.h Create Date: 4 Jan 2007 Modified Date: 24 Aug 2015 diff --git a/docs/settings/linux/c_cpp_properties.json b/docs/settings/linux/c_cpp_properties.json index ce69ca56e3a..53f501fca75 100644 --- a/docs/settings/linux/c_cpp_properties.json +++ b/docs/settings/linux/c_cpp_properties.json @@ -2,7 +2,7 @@ "configurations": [ { "name": "linux", - "includePath": ["${workspaceFolder}/core/include/**", "${workspaceFolder}/common/include/**"], + "includePath": ["${workspaceFolder}/common/include/","${workspaceFolder}/core/include/**"], "defines": [], "compilerPath": "/usr/lib/ccache/clang", "cStandard": "c11", diff --git a/linux/ibus-keyman/tests/Makefile.am b/linux/ibus-keyman/tests/Makefile.am index 2a705520488..041acc0fa92 100644 --- a/linux/ibus-keyman/tests/Makefile.am +++ b/linux/ibus-keyman/tests/Makefile.am @@ -70,7 +70,7 @@ ibus_keyman_tests_SOURCES = \ ../../../core/src/kmx/kmx_environment.cpp \ ../../../core/src/kmx/kmx_environment.h \ ../../../core/src/kmx/kmx_file.cpp \ - ../../../core/src/kmx/kmx_file.h \ + ../../../common/include/kmx_file.h \ ../../../core/src/kmx/kmx_modifiers.cpp \ ../../../core/src/kmx/kmx_options.cpp \ ../../../core/src/kmx/kmx_options.h \ diff --git a/linux/scripts/build.sh b/linux/scripts/build.sh index a5f090848cb..9a6b960f4bf 100755 --- a/linux/scripts/build.sh +++ b/linux/scripts/build.sh @@ -60,12 +60,12 @@ function buildproject() { if [[ "${BUILDONLY}" == "no" ]]; then echo "Configuring $proj" if [[ "${INSTALLDIR}" == "/tmp/kmfl" ]]; then # don't install ibus-kmfl or ibus-keyman into ibus - ../${subdir}$proj/configure KEYMAN_PROC_CFLAGS="-I\$(top_builddir)/../keyboardprocessor/arch/release/include -I\$(top_builddir)/../../core/include" \ + ../${subdir}$proj/configure KEYMAN_PROC_CFLAGS="-I\$(top_builddir)/../keyboardprocessor/arch/release/include -I\$(top_builddir)/../../common/include -I\$(top_builddir)/../../core/include" \ CPPFLAGS="-I\$(top_builddir)/../build-kmflcomp -I\$(top_builddir)/../build-libkmfl" \ KEYMAN_PROC_LIBS="-L`pwd`/../build-libkmfl/src -L`pwd`/../keyboardprocessor/arch/release/src -lkmnkbp0" \ LDFLAGS="-L`pwd`/../build-kmflcomp/src -L`pwd`/../build-libkmfl/src" --prefix=${INSTALLDIR} --libexecdir=${INSTALLDIR}/lib/ibus else # install ibus-kmfl and ibus-keyman into ibus - ../${subdir}$proj/configure KEYMAN_PROC_CFLAGS="-I\$(top_builddir)/../keyboardprocessor/arch/release/include -I\$(top_builddir)/../../core/include" \ + ../${subdir}$proj/configure KEYMAN_PROC_CFLAGS="-I\$(top_builddir)/../keyboardprocessor/arch/release/include -I\$(top_builddir)/../../common/include -I\$(top_builddir)/../../core/include" \ CPPFLAGS="-I\$(top_builddir)/../build-kmflcomp -I\$(top_builddir)/../build-libkmfl" \ LDFLAGS="-L`pwd`/../build-kmflcomp/src -L`pwd`/../build-libkmfl/src" \ KEYMAN_PROC_LIBS="-L`pwd`/../build-libkmfl/src -L`pwd`/../keyboardprocessor/arch/release/src -lkmnkbp0" \ From 515bda769278ca3f1726becd538a58d7fda573b5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 16:13:33 +0200 Subject: [PATCH 18/31] chore(linux): ensure char16_t and namespace --- core/include/keyman/keyboardprocessor_bits.h | 2 ++ core/src/kmx/kmx_processevent.h | 3 +++ core/tests/unit/kmnkbd/test_kmx_xstring.cpp | 3 +++ 3 files changed, 8 insertions(+) diff --git a/core/include/keyman/keyboardprocessor_bits.h b/core/include/keyman/keyboardprocessor_bits.h index 537b943aec3..e3563fd2ec3 100644 --- a/core/include/keyman/keyboardprocessor_bits.h +++ b/core/include/keyman/keyboardprocessor_bits.h @@ -59,4 +59,6 @@ #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_import_flag) #endif +#define KMN_KBP +#define USE_CHAR16_T #include diff --git a/core/src/kmx/kmx_processevent.h b/core/src/kmx/kmx_processevent.h index d410b2fbb28..47088998dce 100644 --- a/core/src/kmx/kmx_processevent.h +++ b/core/src/kmx/kmx_processevent.h @@ -1,6 +1,9 @@ #pragma once +#define KMN_KBP +#define USE_CHAR16_T + #include #include #include diff --git a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp index eec1894c0ad..8e9b38a020c 100644 --- a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp +++ b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp @@ -4,6 +4,9 @@ * Keyman Core - KMX Extended String unit tests */ +#define KMN_KBP +#define USE_CHAR16_T + #include #include #include From 8e36b33f21f0a51c9529689182b6397f1617275a Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 16:29:02 +0200 Subject: [PATCH 19/31] chore(common): check for redefinition of defines --- core/include/keyman/keyboardprocessor_bits.h | 5 +++++ core/src/kmx/kmx_processevent.h | 4 ++++ core/tests/unit/kmnkbd/test_kmx_xstring.cpp | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/core/include/keyman/keyboardprocessor_bits.h b/core/include/keyman/keyboardprocessor_bits.h index e3563fd2ec3..03892a62afb 100644 --- a/core/include/keyman/keyboardprocessor_bits.h +++ b/core/include/keyman/keyboardprocessor_bits.h @@ -59,6 +59,11 @@ #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_import_flag) #endif +#ifndef KMN_KBP #define KMN_KBP +#endif +#ifndef USE_CHAR16_T #define USE_CHAR16_T +#endif + #include diff --git a/core/src/kmx/kmx_processevent.h b/core/src/kmx/kmx_processevent.h index 47088998dce..ef799bb9fd1 100644 --- a/core/src/kmx/kmx_processevent.h +++ b/core/src/kmx/kmx_processevent.h @@ -1,8 +1,12 @@ #pragma once +#ifndef KMN_KBP #define KMN_KBP +#endif +#ifndef USE_CHAR16_T #define USE_CHAR16_T +#endif #include #include diff --git a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp index 8e9b38a020c..104851b7c59 100644 --- a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp +++ b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp @@ -4,8 +4,12 @@ * Keyman Core - KMX Extended String unit tests */ +#ifndef KMN_KBP #define KMN_KBP +#endif +#ifndef USE_CHAR16_T #define USE_CHAR16_T +#endif #include #include From 10d9ed40dcd154a06165486cfabf5fa3066bd549 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 11 Aug 2022 17:51:30 +0200 Subject: [PATCH 20/31] chore(core): use c-compatible type for KMX_UCHAR --- common/include/km_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/include/km_types.h b/common/include/km_types.h index 5cc7257d235..113647d3a0a 100644 --- a/common/include/km_types.h +++ b/common/include/km_types.h @@ -56,7 +56,7 @@ typedef KMX_DWORD *PKMX_DWORD; #ifdef USE_CHAR16_T #define lpuch(x) u ## x -typedef char16_t KMX_UCHAR; +typedef km_kbp_cp KMX_UCHAR; #else #define lpuch(x) L ## x typedef wchar_t KMX_UCHAR; From f9dc68b2e56e13e5e80a99c45af8249fe6d5ed8c Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 11 Aug 2022 16:12:51 -0500 Subject: [PATCH 21/31] docs(core): cleanup in keyboardprocessor.h - fixes to api doc --- core/include/keyman/keyboardprocessor.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/core/include/keyman/keyboardprocessor.h b/core/include/keyman/keyboardprocessor.h index 3e683d06954..e396eaaad08 100644 --- a/core/include/keyman/keyboardprocessor.h +++ b/core/include/keyman/keyboardprocessor.h @@ -650,7 +650,7 @@ undefined. The returned buffer uses UTF-8 encoding. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. ##### Parameters: -- __opts__: An opaque pointer to a state object. +- __state__: An opaque pointer to a state object. - __buf__: A pointer to the buffer to place the C string containing the JSON document into, can be null. - __space__: A pointer to a size_t variable. This variable must contain the @@ -793,7 +793,7 @@ km_kbp_keyboard_get_key_list(km_kbp_keyboard const *keyboard, Free the allocated memory belonging to a keyboard key list previously returned by `km_kbp_keyboard_get_key_list`. ##### Parameters: -- __keyboard__: A pointer to the keyboard key list to be +- __key_list__: A pointer to the keyboard key list to be disposed of. ```c @@ -1118,10 +1118,6 @@ In the event the `state` pointer is null ##### Parameters: - __state__: A pointer to the opaque state object. -- __vk__: A virtual key to be processed. -- __modifier_state__: -The combinations of modifier keys set at the time key `vk` was pressed, bitmask -from the `km_kbp_modifier_state` enum. ```c */ From a7fe8be3f44467b72e4b3a8717270517d59dd6c9 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 12 Aug 2022 08:12:55 +0700 Subject: [PATCH 22/31] chore(web): cleans up UI init timer handling --- web/source/kmwuibutton.ts | 9 +++------ web/source/kmwuifloat.ts | 9 ++++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/web/source/kmwuibutton.ts b/web/source/kmwuibutton.ts index 7591d4a95f0..7c8094b6911 100644 --- a/web/source/kmwuibutton.ts +++ b/web/source/kmwuibutton.ts @@ -279,9 +279,11 @@ if(!window['keyman']['ui']['name']) { * Initialize Button User Interface **/ ui['initialize'] = ui.Initialize = function() { + window.clearTimeout(ui.initTimer); + //Never initialize UI before KMW (parameters will be undefined) if(!keymanweb['initialized']) { - ui.initTimer = window.setTimeout(ui.Initialize,250); + ui.initTimer = window.setTimeout(ui.Initialize, 50); return; } @@ -290,11 +292,6 @@ if(!window['keyman']['ui']['name']) { } ui.init = true; - // While the `ui.init` check above will prevent the timeout's call from - // re-evaluating _this instance_'s method, it can have nasty cross-effects - // in unit testing if not cleared, calling this modules' `Initialize` - // _on a different module_! - window.clearTimeout(ui.initTimer); util['addStyleSheet'](ui._Appearance); diff --git a/web/source/kmwuifloat.ts b/web/source/kmwuifloat.ts index 2cf5f75f662..c32e33ec8f1 100644 --- a/web/source/kmwuifloat.ts +++ b/web/source/kmwuifloat.ts @@ -72,11 +72,12 @@ if(!window['keyman']['ui']['name']) { * Scope Private * Description UI Initialization **/ - ui['initialize'] = ui.Initialize = function() - { + ui['initialize'] = ui.Initialize = function() { + window.clearTimeout(ui.initTimer); + // Must always initialize after keymanWeb itself, otherwise options are undefined if(!keymanweb['initialized']) { - ui.initTimer = window.setTimeout(ui.Initialize,50); + ui.initTimer = window.setTimeout(ui.Initialize, 50); return; } @@ -84,8 +85,6 @@ if(!window['keyman']['ui']['name']) { return; } - window.clearTimeout(ui.initTimer); - var imgPath=util['getOption']('resources')+"ui/float/"; ui.outerDiv = util['createElement']('DIV'); // Container for UI (visible when KeymanWeb is active) From 139b26e4a5ef5717fb98524f8a82a9c3238e240b Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 12 Aug 2022 11:12:27 +0200 Subject: [PATCH 23/31] chore(linux): update tar ignore for common folder --- linux/scripts/dist.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/linux/scripts/dist.sh b/linux/scripts/dist.sh index 5398932d661..7bc54e37225 100755 --- a/linux/scripts/dist.sh +++ b/linux/scripts/dist.sh @@ -68,14 +68,17 @@ for proj in ${extra_projects}; do dpkg-source --tar-ignore=*~ --tar-ignore=.git --tar-ignore=.gitattributes \ --tar-ignore=.gitignore --tar-ignore=experiments --tar-ignore=debian \ --tar-ignore=.github --tar-ignore=.vscode --tar-ignore=android \ - --tar-ignore=common --tar-ignore=developer --tar-ignore=docs --tar-ignore=ios \ + --tar-ignore=common/models --tar-ignore=common/predictive-text \ + --tar-ignore=common/resources --tar-ignore=common/schemas \ + --tar-ignore=common/test --tar-ignore=common/web --tar-ignore=common/windows \ + --tar-ignore=developer --tar-ignore=docs --tar-ignore=ios \ --tar-ignore=linux/keyman-config/buildtools/build-langtags.py --tar-ignore=__pycache__ \ --tar-ignore=linux/help --tar-ignore=linux/Jenkinsfile \ --tar-ignore=linux/keyboardprocessor --tar-ignore=linux/legacy \ --tar-ignore=mac --tar-ignore=node_modules --tar-ignore=oem \ --tar-ignore=linux/build* --tar-ignore=core/build \ --tar-ignore=resources/devbox --tar-ignore=resources/git-hooks \ - --tar-ignore=resources/scopes --tar-ignore=common/web \ + --tar-ignore=resources/scopes \ --tar-ignore=resources/build/*.lua --tar-ignore=resources/build/jq* \ --tar-ignore=resources/build/vswhere* --tar-ignore=results \ --tar-ignore=web --tar-ignore=windows --tar-ignore=keyman_1* \ From 131525bac5a282d27e4c0f23ef68b6627f02ba5a Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 12 Aug 2022 14:01:57 -0400 Subject: [PATCH 24/31] auto: increment master version to 16.0.47 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 58aeca1081a..685a5c7df9d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 16.0.46 alpha 2022-08-12 + +* docs(core): cleanup in keyboardprocessor.h (#7065) + ## 16.0.45 alpha 2022-08-09 * feat(linux): Replace deprecated distutils (#7051) diff --git a/VERSION.md b/VERSION.md index 8018df015ce..e337b51eb4c 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -16.0.46 \ No newline at end of file +16.0.47 \ No newline at end of file From 5084f6feae8ce3f1b3f2fbb79ed29723b0294d4f Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 15 Aug 2022 15:14:57 -0400 Subject: [PATCH 25/31] auto: increment master version to 16.0.48 --- HISTORY.md | 8 ++++++++ VERSION.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 685a5c7df9d..775866a8cf1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,13 @@ # Keyman Version History +## 16.0.47 alpha 2022-08-15 + +* chore(core): refactor kmx_file.h to common (#7062) +* fix(developer): stack overflow when compiling non-web keyboard (#7031) +* fix(developer): prevent crash attempting to compile ansi keyboard (#7033) +* chore(linux): Refactor `jenkins.sh` (#7060) +* fix(developer): compiler emitting garbage for readonly groups (#7013) + ## 16.0.46 alpha 2022-08-12 * docs(core): cleanup in keyboardprocessor.h (#7065) diff --git a/VERSION.md b/VERSION.md index e337b51eb4c..84f71677bff 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -16.0.47 \ No newline at end of file +16.0.48 \ No newline at end of file From 760a20e97feea5a270da1c884566687a19a76188 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Tue, 16 Aug 2022 08:13:01 +0700 Subject: [PATCH 26/31] chore(web): Apply suggestions from code review Co-authored-by: Marc Durdin --- web/source/kmwuibutton.ts | 5 ++++- web/source/kmwuifloat.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/web/source/kmwuibutton.ts b/web/source/kmwuibutton.ts index 7c8094b6911..1205c7b6e40 100644 --- a/web/source/kmwuibutton.ts +++ b/web/source/kmwuibutton.ts @@ -279,7 +279,10 @@ if(!window['keyman']['ui']['name']) { * Initialize Button User Interface **/ ui['initialize'] = ui.Initialize = function() { - window.clearTimeout(ui.initTimer); + if(ui.initTimer) { + window.clearTimeout(ui.initTimer); + ui.initTimer = null; + } //Never initialize UI before KMW (parameters will be undefined) if(!keymanweb['initialized']) { diff --git a/web/source/kmwuifloat.ts b/web/source/kmwuifloat.ts index c32e33ec8f1..b9313f6e2f9 100644 --- a/web/source/kmwuifloat.ts +++ b/web/source/kmwuifloat.ts @@ -73,7 +73,10 @@ if(!window['keyman']['ui']['name']) { * Description UI Initialization **/ ui['initialize'] = ui.Initialize = function() { - window.clearTimeout(ui.initTimer); + if(ui.initTimer) { + window.clearTimeout(ui.initTimer); + ui.initTimer = null; + } // Must always initialize after keymanWeb itself, otherwise options are undefined if(!keymanweb['initialized']) { From 3fe24996b31ce811f7d2d4c05c75761cbc2fb313 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 16 Aug 2022 14:02:02 -0400 Subject: [PATCH 27/31] auto: increment master version to 16.0.49 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 775866a8cf1..1878d3ad4a4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 16.0.48 alpha 2022-08-16 + +* fix(web): button, float init timer cleanup (#7036) + ## 16.0.47 alpha 2022-08-15 * chore(core): refactor kmx_file.h to common (#7062) diff --git a/VERSION.md b/VERSION.md index 84f71677bff..214271b7a31 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -16.0.48 \ No newline at end of file +16.0.49 \ No newline at end of file From f2fe3b16938ffd03fc553b5927ac6dba0652fce7 Mon Sep 17 00:00:00 2001 From: Ross Date: Wed, 17 Aug 2022 11:39:16 +1000 Subject: [PATCH 28/31] fix: remove saving and restoring context kbd options Remove the saving of context and keyboard options on the non updateable call to process hook. The windows Text Input Processor calls twice one call is not updateable. With the core integeration we run the processor only once, preserving the actions and context to be applied on the updatable call. --- windows/src/engine/keyman32/appint/aiTIP.cpp | 26 ++++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/windows/src/engine/keyman32/appint/aiTIP.cpp b/windows/src/engine/keyman32/appint/aiTIP.cpp index 9043c9ece16..23240b2a067 100644 --- a/windows/src/engine/keyman32/appint/aiTIP.cpp +++ b/windows/src/engine/keyman32/appint/aiTIP.cpp @@ -258,15 +258,12 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM _td->TIPGetContext = ctfunc; AppContextWithStores *savedContext = NULL; // I4370 // I4978 - AppContext *savedContextUsingCore = NULL; // used for common core - km_kbp_option_item *SavedKBDOptions = NULL; // used for common core + if (!Updateable) { - if (isUsingCoreProcessor) { - savedContextUsingCore = new AppContext(); - _td->app->CopyContext(savedContextUsingCore); - SavedKBDOptions = SaveKeyboardOptionsCore(_td->lpActiveKeyboard); - } else { // I4370 - savedContext = new AppContextWithStores(_td->lpActiveKeyboard->Keyboard->cxStoreArray); // I4978 + // The core processor km_kbp_process_event is only called once per key stroke + // therefore there is no need to preserve context and keyboard actions + if (!isUsingCoreProcessor) { + savedContext = new AppContextWithStores(_td->lpActiveKeyboard->Keyboard->cxStoreArray); // I4370 // I4978 _td->app->SaveContext(savedContext); } } @@ -274,17 +271,8 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM BOOL res = ProcessHook(); if (!Updateable) { - if (isUsingCoreProcessor) { - if (res) { - // Reset the context if match found - _td->app->RestoreContextOnly(savedContextUsingCore); - RestoreKeyboardOptionsCore(_td->lpActiveKeyboard->lpCoreKeyboardState, SavedKBDOptions); - DisposeKeyboardOptionsCore(&SavedKBDOptions); - delete savedContextUsingCore; - savedContextUsingCore = NULL; - } - } else { // I4370 - if (res) { // I4585 + if (!isUsingCoreProcessor) { + if (res) { // I4585 // I4370 // Reset the context if match found _td->app->RestoreContext(savedContext); delete savedContext; From ea50559fc155f40e840e14d564a6fcfb67898731 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Aug 2022 19:58:19 +0000 Subject: [PATCH 29/31] chore(deps): bump @actions/core from 1.8.2 to 1.9.1 Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.8.2 to 1.9.1. - [Release notes](https://github.com/actions/toolkit/releases) - [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core) --- updated-dependencies: - dependency-name: "@actions/core" dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++++++++++------------- resources/build/version/package.json | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index ad25cc7212c..03dd8ee2b05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -577,8 +577,8 @@ "typescript": "^4.5.4" }, "optionalDependencies": { - "hetrodo-node-hide-console-window-napi": "keymanapp/hetrodo-node-hide-console-window-napi#keyman-15.0", - "node-windows-trayicon": "keymanapp/node-windows-trayicon#keyman-15.0" + "hetrodo-node-hide-console-window-napi": "git+ssh://git@github.com/keymanapp/hetrodo-node-hide-console-window-napi.git#858b23036a9963b40ad6ff3c5bacd421e5839b92", + "node-windows-trayicon": "git+ssh://git@github.com/keymanapp/node-windows-trayicon.git#1e46786082213f3edcddd5953e33f5abdc7ea05f" } }, "developer/src/server/node_modules/@cspotcode/source-map-support": { @@ -865,11 +865,12 @@ "dev": true }, "node_modules/@actions/core": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.8.2.tgz", - "integrity": "sha512-FXcBL7nyik8K5ODeCKlxi+vts7torOkoDAKfeh61EAkAy1HAvwn9uVzZBY0f15YcQTcZZ2/iSGBFHEuioZWfDA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", + "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", "dependencies": { - "@actions/http-client": "^2.0.1" + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" } }, "node_modules/@actions/github": { @@ -6867,7 +6868,7 @@ "name": "@keymanapp/auto-history-action", "license": "MIT", "dependencies": { - "@actions/core": "^1.2.6", + "@actions/core": "^1.9.1", "@actions/github": "^2.1.0", "typescript": "^4.5.4", "yargs": "^15.1.0" @@ -7122,11 +7123,12 @@ }, "dependencies": { "@actions/core": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.8.2.tgz", - "integrity": "sha512-FXcBL7nyik8K5ODeCKlxi+vts7torOkoDAKfeh61EAkAy1HAvwn9uVzZBY0f15YcQTcZZ2/iSGBFHEuioZWfDA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", + "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", "requires": { - "@actions/http-client": "^2.0.1" + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" } }, "@actions/github": { @@ -7188,7 +7190,7 @@ "@keymanapp/auto-history-action": { "version": "file:resources/build/version", "requires": { - "@actions/core": "^1.2.6", + "@actions/core": "^1.9.1", "@actions/github": "^2.1.0", "@types/node": "^13.7.0", "@types/semver": "^7.1.0", @@ -7355,11 +7357,11 @@ "chalk": "^4.1.2", "copyfiles": "^2.4.1", "express": "^4.17.2", - "hetrodo-node-hide-console-window-napi": "keymanapp/hetrodo-node-hide-console-window-napi#keyman-15.0", + "hetrodo-node-hide-console-window-napi": "git+ssh://git@github.com/keymanapp/hetrodo-node-hide-console-window-napi.git#858b23036a9963b40ad6ff3c5bacd421e5839b92", "mocha": "^9.1.4", "multer": "^1.4.4", "ngrok": "^4.2.2", - "node-windows-trayicon": "keymanapp/node-windows-trayicon#keyman-15.0", + "node-windows-trayicon": "git+ssh://git@github.com/keymanapp/node-windows-trayicon.git#1e46786082213f3edcddd5953e33f5abdc7ea05f", "open": "^8.4.0", "ts-node": "^10.4.0", "tsc-watch": "^4.5.0", diff --git a/resources/build/version/package.json b/resources/build/version/package.json index 1a4e8355c87..33698434fb7 100644 --- a/resources/build/version/package.json +++ b/resources/build/version/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "@actions/core": "^1.2.6", + "@actions/core": "^1.9.1", "@actions/github": "^2.1.0", "typescript": "^4.5.4", "yargs": "^15.1.0" From b03e7ca32f7eadf368714b4d14f11f5f9316977a Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 22 Aug 2022 17:46:27 +0200 Subject: [PATCH 30/31] chore(core): Remove obsolete python keyboardprocessor This seems to be not used anywhere and has diverged from the API. --- core/python/keyman/keyboardprocessor/_api.py | 573 ------------------- core/python/keyman/keyboardprocessor/api.py | 118 ---- 2 files changed, 691 deletions(-) delete mode 100644 core/python/keyman/keyboardprocessor/_api.py delete mode 100644 core/python/keyman/keyboardprocessor/api.py diff --git a/core/python/keyman/keyboardprocessor/_api.py b/core/python/keyman/keyboardprocessor/_api.py deleted file mode 100644 index 0f2f59bd2c9..00000000000 --- a/core/python/keyman/keyboardprocessor/_api.py +++ /dev/null @@ -1,573 +0,0 @@ -# Copyright: © 2018 SIL International. -# Description: Lowlevel C style python API. Intended to be wrapped by a more -# Pythonic higher level API. -# Create Date: 18 Oct 2018 -# Authors: Tim Eves (TSE) -# - -import ctypes -import ctypes.util -import operator -import os -from enum import auto, IntEnum, IntFlag -from ctypes import (c_uint8, - c_uint16, c_uint32, - c_size_t, - c_void_p, c_char_p, - Structure, Union, POINTER, CFUNCTYPE) -from typing import Any, Tuple - -CP = c_uint16 -USV = c_uint32 -VirtualKey = c_uint16 - -libpath = os.environ.get('PYKMNKBD_LIBRARY_PATH', - ctypes.util.find_library("kmnkbp0")) - -libkbp = ctypes.cdll.LoadLibrary(libpath) - - -# Error handling -# ============== -class StatusCode(IntEnum): - OK = 0 - NO_MEM = auto() - IO_ERROR = auto() - INVALID_ARGUMENT = auto() - KEY_ERROR = auto() - OS_ERROR = 0x80000000 - - -Status = c_uint32 - - -def __map_oserror(code: Status) -> str: - code = StatusCode.OS_ERROR ^ code - msg = '{0!s}: OS error code (' + code + '): ' + os.strerror(code) - return msg, lambda m: OSError(code, m) - - -__exceptions_map = [ - (None, '{0!s}: Success'), - (MemoryError, '{0!s}: memory allocation failed.'), - (RuntimeError, '{0!s}: IO Error: {1!s}'), - (ValueError, '{0!s}: Invalid argument passed.'), - (LookupError, '{0!s}: Item does not exist in: {1!s}'), - (OSError, __map_oserror)] - - -def status_code(code: Status, func, args): - if code == StatusCode.OK: return args - exc, msg = __exceptions_map[code] - if callable(msg): msg = msg(code) - raise exc(msg.format(libkbp._name, *args)) - - -def null_check(code, func, args): - if code is not None: return args - raise KeyError(args[1] + ': Not found in collection') - - -class Dir(IntFlag): - IN = auto() - OUT = auto() - OPT = auto() - - -def __method(iface: str, method: str, result, - *args: Tuple[Any, Dir, str], **kwds): - proto = CFUNCTYPE(result, *map(operator.itemgetter(0), args)) - params = tuple(a[1:] for a in args) - c_name = iface+'_'+method if iface else method - f = proto(('km_kbp_' + c_name, libkbp), params) - if 'errcheck' in kwds: f.errcheck = kwds.get('errcheck') - globals()[c_name] = f - - -# Context processing -# ================== -Context_p = c_void_p - - -class ContextType(IntEnum): - END = 0 - CHAR = auto() - MARKER = auto() - - -class ContextItem(Structure): - class __ContextValue(Union): - _fields_ = (('character', USV), - ('marker', c_uint32)) - _anonymous_ = ('value',) - _fields_ = (('type', c_uint8), - ('value', __ContextValue)) - - -__method('context_items', 'from_utf16', Status, - (c_void_p, Dir.IN, 'text'), - (POINTER(POINTER(ContextItem)), Dir.OUT, 'context_items'), - errcheck=status_code) - -__method('context_items', 'to_utf16', c_size_t, - (POINTER(ContextItem), Dir.IN, 'context_items'), - (c_void_p, Dir.IN | Dir.OPT, 'buffer'), - (c_size_t, Dir.IN | Dir.OPT, 'buffer_size')) - -__method('context_items', 'dispose', None, - (POINTER(ContextItem), Dir.IN, 'context_items')) - -__method('context', 'set', Status, - (Context_p, Dir.IN, 'context'), - (POINTER(ContextItem), Dir.IN, 'context_items'), - errcheck=status_code) - -__method('context', 'get', POINTER(ContextItem), - (Context_p, Dir.IN, 'context')) - -__method('context', 'clear', None, (Context_p, Dir.IN, 'context')) - -__method('context', 'length', c_size_t, (Context_p, Dir.IN, 'context')) - -__method('context', 'append', Status, - (Context_p, Dir.IN, 'context'), - (POINTER(ContextItem), Dir.IN, 'context_items'), - errcheck=status_code) - -__method('context', 'shrink', Status, - (Context_p, Dir.IN, 'context'), - (c_size_t, Dir.IN, 'num'), - (POINTER(ContextItem), Dir.IN, 'prefix'), - errcheck=status_code) - - -class ActionItem(Structure): - class __ActionItem(Union): - _fields_ = (('marker', c_size_t), - ('option', c_char_p), - ('character', USV), - ('vkey', VirtualKey)) - _anonymous_ = ('data',) - _fields_ = (('type', c_uint8), - ('reserved', c_uint8*3), - ('data', __ActionItem)) - - -class ActionType(IntEnum): - END = 0 # Marks end of action items list. - CHAR = 1 - MARKER = 2 # correlates to kmn's "deadkey" markers - ALERT = 3 - BACK = 4 - PERSIST_OPT = 5 - RESET_OPT = 6 - VKEYDOWN = 7 - VKEYUP = 8 - VSHIFTDOWN = 9 - VSHIFTUP = 10 - MAX_TYPE_ID = auto() - - -# Option processing -# ================= -OptionSet_p = c_void_p - - -class OptionScope(IntEnum): - UNKNOWN = auto() - KEYBOARD = auto() - ENVIRONMENT = auto() - - -class Option(Structure): - _fields_ = (('key', c_char_p), - ('value', c_char_p), - ('scope', c_uint8)) - - -Option.END = Option(None, None) - -__method('options_set', 'size', c_size_t, (OptionSet_p, Dir.IN, 'opts')) - -__method('options_set', 'lookup', POINTER(Option), - (OptionSet_p, Dir.IN, 'opts'), - (c_char_p, Dir.IN, 'key'), - errcheck=null_check) - -__method('options_set', 'update', Status, - (OptionSet_p, Dir.IN, 'opts'), - (POINTER(Option), Dir.IN, 'new_opts'), - errcheck=status_code) - -__method('options_set', 'to_json', Status, - (OptionSet_p, Dir.IN, 'opts'), - (c_char_p, Dir.IN | Dir.OPT, 'buffer'), - (c_size_t, Dir.IN | Dir.OUT, 'space'), - errcheck=status_code) - - -# Keyboards -# ========= -Keyboard_p = c_void_p - - -class KeyboardAttrs(Structure): - _fields_ = (('version_string', c_char_p), - ('id', c_char_p), - ('folder_path', c_char_p), - ('default_options', OptionSet_p)) - - -__method('keyboard', 'load', Status, - (c_char_p, Dir.IN, 'path'), - (POINTER(Keyboard_p), Dir.OUT, 'kb'), - errcheck=status_code) - -__method('keyboard', 'dispose', None, (Keyboard_p, Dir.IN, 'kb')) - -__method('keyboard', 'get_attrs', POINTER(KeyboardAttrs), - (Keyboard_p, Dir.IN, 'keyboard')) - - -# State processing -# ================ -State_p = c_void_p - -__method('state', 'create', Status, - (Keyboard_p, Dir.IN, 'keyboard'), - (POINTER(Option), Dir.IN, 'env',), - (POINTER(State_p), Dir.OUT, 'out'), - errcheck=status_code) - -__method('state', 'clone', Status, - (State_p, Dir.IN, 'state'), - (POINTER(State_p), Dir.OUT, 'out'), - errcheck=status_code) - -__method('state', 'dispose', None, (State_p, Dir.IN, 'state')) - -__method('state', 'context', Context_p, (State_p, Dir.IN, 'state')) - -__method('state', 'options', OptionSet_p, (State_p, Dir.IN, 'state')) - -__method('state', 'action_items', POINTER(ActionItem), - (State_p, Dir.IN, 'state'), - (POINTER(c_size_t), Dir.OUT, 'num_items')) - -__method('state', 'to_json', Status, - (State_p, Dir.IN, 'state'), - (c_char_p, Dir.IN | Dir.OPT, 'buffer'), - (c_size_t, Dir.IN | Dir.OUT, 'space'), - errcheck=status_code) - - -# Processor -# ========= -class Attributes(Structure): - _fields_ = (('max_context', c_size_t), - ('current', c_uint16), - ('revision', c_uint16), - ('age', c_uint16), - ('technology', c_uint16), - ('vendor', c_char_p)) - - -class Tech(IntFlag): - UNSPECIFIED = 0 - KMN = 1 - LDML = 2 - - -__method(None, 'get_engine_attrs', POINTER(Attributes)) - -__method(None, 'process_event', Status, - (State_p, Dir.IN, 'state'), - (VirtualKey, Dir.IN, 'vkey'), - (c_uint16, Dir.IN, 'modifier_state')) - - -class Modifier(IntFlag): - LCTRL = 1 << 0 - RCTRL = 1 << 1 - LALT = 1 << 2 - RALT = 1 << 3 - SHIFT = 1 << 4 - CTRL = 1 << 5 - ALT = 1 << 6 - CAPS = 1 << 7 - NOCAPS = 1 << 8 - NUMLOCK = 1 << 9 - NONUMLOCK = 1 << 10 - SCROLLOCK = 1 << 11 - NOSCROLLOCK = 1 << 12 - VIRTUALKEY = 1 << 13 - - -class ModifierMask(IntFlag): - ALL = 0x7f - ALT_GR_SIM = Modifier.LCTRL | Modifier.LALT - CHIRAL = 0x1f - IS_CHIRAL = 0x0f - NON_CHIRAL = 0x7f - CAPS = 0x0300 - NUMLOCK = 0x0C00 - SCROLLLOCK = 0x3000 - - -class VKey(IntEnum): - _00 = auto() - LBUTTON = auto() - RBUTTON = auto() - CANCEL = auto() - MBUTTON = auto() - _05 = auto() - _06 = auto() - _07 = auto() - BKSP = auto() - KTAB = auto() - _0A = auto() - _0B = auto() - KP5 = auto() - ENTER = auto() - _0E = auto() - _0F = auto() - SHIFT = auto() - CONTROL = auto() - ALT = auto() - PAUSE = auto() - CAPS = auto() - _15 = auto() - _16 = auto() - _17 = auto() - _18 = auto() - _19 = auto() - _1A = auto() - ESC = auto() - _1C = auto() - _1D = auto() - _1E = auto() - _1F = auto() - SPACE = auto() - PGUP = auto() - PGDN = auto() - END = auto() - HOME = auto() - LEFT = auto() - UP = auto() - RIGHT = auto() - DOWN = auto() - SEL = auto() - PRINT = auto() - EXEC = auto() - PRTSCN = auto() - INS = auto() - DEL = auto() - HELP = auto() - K0 = auto() - K1 = auto() - K2 = auto() - K3 = auto() - K4 = auto() - K5 = auto() - K6 = auto() - K7 = auto() - K8 = auto() - K9 = auto() - _3A = auto() - _3B = auto() - _3C = auto() - _3D = auto() - _3E = auto() - _3F = auto() - _40 = auto() - KA = auto() - KB = auto() - KC = auto() - KD = auto() - KE = auto() - KF = auto() - KG = auto() - KH = auto() - KI = auto() - KJ = auto() - KK = auto() - KL = auto() - KM = auto() - KN = auto() - KO = auto() - KP = auto() - KQ = auto() - KR = auto() - KS = auto() - KT = auto() - KU = auto() - KV = auto() - KW = auto() - KX = auto() - KY = auto() - KZ = auto() - _5B = auto() - _5C = auto() - _5D = auto() - _5E = auto() - _5F = auto() - NP0 = auto() - NP1 = auto() - NP2 = auto() - NP3 = auto() - NP4 = auto() - NP5 = auto() - NP6 = auto() - NP7 = auto() - NP8 = auto() - NP9 = auto() - NPSTAR = auto() - NPPLUS = auto() - SEPARATOR = auto() - NPMINUS = auto() - NPDOT = auto() - NPSLASH = auto() - F1 = auto() - F2 = auto() - F3 = auto() - F4 = auto() - F5 = auto() - F6 = auto() - F7 = auto() - F8 = auto() - F9 = auto() - F10 = auto() - F11 = auto() - F12 = auto() - F13 = auto() - F14 = auto() - F15 = auto() - F16 = auto() - F17 = auto() - F18 = auto() - F19 = auto() - F20 = auto() - F21 = auto() - F22 = auto() - F23 = auto() - F24 = auto() - _88 = auto() - _89 = auto() - _8A = auto() - _8B = auto() - _8C = auto() - _8D = auto() - _8E = auto() - _8F = auto() - NUMLOCK = auto() - SCROLL = auto() - _92 = auto() - _93 = auto() - _94 = auto() - _95 = auto() - _96 = auto() - _97 = auto() - _98 = auto() - _99 = auto() - _9A = auto() - _9B = auto() - _9C = auto() - _9D = auto() - _9E = auto() - _9F = auto() - _A0 = auto() - _A1 = auto() - _A2 = auto() - _A3 = auto() - _A4 = auto() - _A5 = auto() - _A6 = auto() - _A7 = auto() - _A8 = auto() - _A9 = auto() - _AA = auto() - _AB = auto() - _AC = auto() - _AD = auto() - _AE = auto() - _AF = auto() - _B0 = auto() - _B1 = auto() - _B2 = auto() - _B3 = auto() - _B4 = auto() - _B5 = auto() - _B6 = auto() - _B7 = auto() - _B8 = auto() - _B9 = auto() - COLON = auto() - EQUAL = auto() - COMMA = auto() - HYPHEN = auto() - PERIOD = auto() - SLASH = auto() - BKQUOTE = auto() - _C1 = auto() - _C2 = auto() - _C3 = auto() - _C4 = auto() - _C5 = auto() - _C6 = auto() - _C7 = auto() - _C8 = auto() - _C9 = auto() - _CA = auto() - _CB = auto() - _CC = auto() - _CD = auto() - _CE = auto() - _CF = auto() - _D0 = auto() - _D1 = auto() - _D2 = auto() - _D3 = auto() - _D4 = auto() - _D5 = auto() - _D6 = auto() - _D7 = auto() - _D8 = auto() - _D9 = auto() - _DA = auto() - LBRKT = auto() - BKSLASH = auto() - RBRKT = auto() - QUOTE = auto() - oDF = auto() - oE0 = auto() - oE1 = auto() - oE2 = auto() - oE3 = auto() - oE4 = auto() - _E5 = auto() - oE6 = auto() - _E7 = auto() - _E8 = auto() - oE9 = auto() - oEA = auto() - oEB = auto() - oEC = auto() - oED = auto() - oEE = auto() - oEF = auto() - oF0 = auto() - oF1 = auto() - oF2 = auto() - oF3 = auto() - oF4 = auto() - oF5 = auto() - _F6 = auto() - _F7 = auto() - _F8 = auto() - _F9 = auto() - _FA = auto() - _FB = auto() - _FC = auto() - _FD = auto() - _FE = auto() - _FF = auto() diff --git a/core/python/keyman/keyboardprocessor/api.py b/core/python/keyman/keyboardprocessor/api.py deleted file mode 100644 index 6fcedf18e54..00000000000 --- a/core/python/keyman/keyboardprocessor/api.py +++ /dev/null @@ -1,118 +0,0 @@ -import pathlib -from typing import NamedTuple, NewType, Tuple, List, Union -from enum import Enum -from collections.abc import Sequence, Mapping - -USV = int -Marker = int -VirtualKey = int - - -class Context(Sequence): - Item = Union[USV, Marker] - - def __init__(initial: str): - pass - - def __del__(self): - pass - - def __str__(self): - pass - - def set(self, ctxt: List[Item]): - self.clear() - self.apped(ctxt) - - def clear(self): - pass - - def __getitem__(self, key: int) -> Item: - pass - - def __len__(self): - pass - - def append(self, ctxt: List[Item]): - pass - - def delete(self, remove_n: int, prefix: List[Item]): - pass - - -Option = Tuple[str, str] - - -class OptionSet(Mapping): - def __getitem__(self, key: str) -> Option: - pass - - def __iter__(self): - pass - - def __len__(self): - pass - - def __str__(self): - pass - - -class Keyboard(NamedTuple('__kb_attrs', version=str, id=str, folder_path=pathlib.Path, default_options=OptionSet)): - def __new__(cls, _): - return super(Keyboard, cls).__new__(cls, *[None]*4) - - def __init__(self, kb_path: pathlib.Path): - pass - - def __del__(self): - pass - - -class Action: - VKeyDown = NewType('Action.VirtualKey', VirtualKey) - # VKeyUp = VirtualKey - # VShiftDown = VirtualKey - # VShiftUp = VirtualKey - # Char = int - # Marker = int - # Bell = NewType('Bell', None) - # Back = NewType('Back', None) - # PersistOpt = str - # ResetOpt = str - - -ActionList = List[Action] - - -class State: - def __init__(self, kb: Keyboard, env: OptionSet): - pass - - def __del__(self): - pass - - @property - def flags(self) -> int: - pass - - @property - def context(self) -> Context: - pass - - @property - def environment(self) -> OptionSet: - pass - - @property - def options(self) -> OptionSet: - pass - - def indentify_option_src(opt: Option): - pass - - -def process_event(vk: VirtualKey, - modifier_state, - state: State, - acts: ActionList): - pass From d92ac6e4d1889f257d55247aa7143a8660588bec Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 22 Aug 2022 14:02:00 -0400 Subject: [PATCH 31/31] auto: increment master version to 16.0.50 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1878d3ad4a4..0c1646e28e8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 16.0.49 alpha 2022-08-22 + +* fix: remove saving and restoring context kbd options (#7077) +* chore(deps): bump @actions/core from 1.8.2 to 1.9.1 (#7087) + ## 16.0.48 alpha 2022-08-16 * fix(web): button, float init timer cleanup (#7036) diff --git a/VERSION.md b/VERSION.md index 214271b7a31..245e8fdca3f 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -16.0.49 \ No newline at end of file +16.0.50 \ No newline at end of file