diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 32544e993a..ec57ef957d 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -43,7 +43,7 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js"); /* * Core functions */ - (function(){ + (function() { // Privileged (public) methods this.getStorageDirectory = getStorageDirectory; this.debug = debug; @@ -1348,7 +1348,49 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js"); } return errors; } - + + this.isWin64EmulatedOnArm = function () { + if (!this.isWin) { + return false; + } + + if (Services.sysinfo.getProperty("build") < 22000) { + // GetMachineTypeAttributes is only available on Windows 11 and later + return false; + } + + if (this.arch !== "x86_64") { + // We only check if x86_64 build is running on ARM + return false; + } + + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ne-processthreadsapi-machine_attributes + const userEnabled = 0x00000001; + + let { ctypes } = ChromeUtils.importESModule( + "resource://gre/modules/ctypes.sys.mjs" + ); + try { + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getmachinetypeattributes + let kernel32 = ctypes.open("Kernel32"); + let getMachineTypeAttributesC = kernel32.declare( + "GetMachineTypeAttributes", + ctypes.winapi_abi, + ctypes.int, + ctypes.unsigned_short, + ctypes.int.ptr + ); + let aa64 = 0xaa64; + let output = ctypes.int(); + getMachineTypeAttributesC(aa64, output.address()); + kernel32.close(); + return !!(output.value & userEnabled); + } + catch (e) { + Zotero.logError(e); + return false; + } + } /** * Get versions, platform, etc. @@ -1367,7 +1409,7 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js"); if (Zotero.isWin) { let info = await Services.sysinfo.processInfo; - if (info.isWowARM64) { + if (info.isWowARM64 || this.isWin64EmulatedOnArm()) { version += " on ARM64"; } else if (info.isWow64) { diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index 21522b0662..066d2590c0 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -6115,19 +6115,30 @@ var ZoteroPane = new function() this.showArchitectureWarning = async function () { const remindInterval = 60 * 60 * 24 * 30; - const isWow64 = (await Services.sysinfo.processInfo).isWow64; - const is32bitBuild = Zotero.arch === 'x86'; const lastDisplayed = Zotero.Prefs.get('architecture.warning.lastDisplayed') ?? 0; if (lastDisplayed > Math.round(Date.now() / 1000) - remindInterval) { return; } - - if (Zotero.isWin && isWow64 && is32bitBuild) { + + const isWow64 = (await Services.sysinfo.processInfo).isWow64; + const isX64OnArm = Zotero.isWin64EmulatedOnArm(); + + if (Zotero.isWin && (isWow64 || isX64OnArm)) { let panel = document.getElementById('architecture-warning-container'); let action = document.getElementById('architecture-warning-action'); let close = document.getElementById('architecture-warning-close'); let remind = document.getElementById('architecture-warning-remind'); + let message = document.getElementById('architecture-warning-message'); + + if (isWow64) { + message.dataset.l10nId = 'architecture-win32-warning-message'; + action.dataset.l10nId = 'architecture-warning-action'; + } + else if (isX64OnArm) { + message.dataset.l10nId = 'architecture-x64-on-arm64-message'; + action.dataset.l10nId = 'architecture-x64-on-arm64-action'; + } panel.removeAttribute('collapsed'); action.onclick = function () { diff --git a/chrome/content/zotero/zoteroPane.xhtml b/chrome/content/zotero/zoteroPane.xhtml index 49fff6b8d5..e900988bf5 100644 --- a/chrome/content/zotero/zoteroPane.xhtml +++ b/chrome/content/zotero/zoteroPane.xhtml @@ -1141,12 +1141,12 @@ - diff --git a/chrome/locale/en-US/zotero/zotero.ftl b/chrome/locale/en-US/zotero/zotero.ftl index e21c57feb6..96cc59612b 100644 --- a/chrome/locale/en-US/zotero/zotero.ftl +++ b/chrome/locale/en-US/zotero/zotero.ftl @@ -630,6 +630,8 @@ locate-library-lookup-no-resolver = You must choose a resolver from the { $pane architecture-win32-warning-message = { -app-name } is running in 32-bit mode on a 64-bit version of Windows. { -app-name } will run more efficiently in 64-bit mode. architecture-warning-action = Download 64-bit { -app-name } +architecture-x64-on-arm64-message = { -app-name } is running in emulated mode. A native version of { -app-name } will run more efficiently. +architecture-x64-on-arm64-action = Download { -app-name } for ARM64 first-run-guidance-quickFormat = Type a title, author, and/or year to search for a reference. diff --git a/scss/_zotero.scss b/scss/_zotero.scss index fbbada6228..f6cdd80432 100644 --- a/scss/_zotero.scss +++ b/scss/_zotero.scss @@ -23,7 +23,7 @@ @import "components/advancedSearch"; @import "components/annotation"; @import "components/autosuggest"; -@import "components/banner"; +@import "components/banners"; @import "components/button"; @import "components/clicky"; @import "components/contextPane"; @@ -64,7 +64,7 @@ @import "components/tabsMenu"; @import "components/newCollectionDialog"; @import "components/reader"; -@import "components/banners"; + // Elements // -------------------------------------------------- diff --git a/scss/components/_banner.scss b/scss/components/_banner.scss deleted file mode 100644 index b325556125..0000000000 --- a/scss/components/_banner.scss +++ /dev/null @@ -1,50 +0,0 @@ -.banner { - border-bottom: var(--color-panedivider) .5px solid; - display: flex; - font-size: 1.03846154em; - font-weight: 600; - justify-content: center; - line-height: 2.07692308em; - overflow: hidden; - padding: 0 2em; - - .message { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } - - > .spacer { - flex: 1; - } - - > a { - border: none; - color: inherit; - margin: 0; - padding: 0 .5em; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } - - // extra space after the last link after spacer, i.e., the one immediately before the X button - .spacer ~ a:last-of-type { - padding-right: 1em; - } - - > label { - color: inherit; - cursor: pointer; - font-size: 1.69230769em; - position: absolute; - right: 9px; - text-decoration: none; - top: -3px; - } -} - -#architecture-warning-container { - background-color: var(--accent-red); - color: white; -} \ No newline at end of file diff --git a/scss/components/_banners.scss b/scss/components/_banners.scss index 748870a230..c64336c29d 100644 --- a/scss/components/_banners.scss +++ b/scss/components/_banners.scss @@ -1,4 +1,4 @@ -#post-upgrade-banner, #retracted-items-banner, #sync-reminder-banner { +#post-upgrade-banner, #retracted-items-banner, #sync-reminder-banner, #architecture-warning-banner { @include macOS-normalize-controls; display: flex; @@ -60,7 +60,7 @@ } } -#retracted-items-banner, #sync-reminder-banner { +#retracted-items-banner, #sync-reminder-banner, #architecture-warning-banner { line-height: 2.2em; font-size: 13.5px; padding: 0 2em; @@ -110,3 +110,24 @@ } } } + +#architecture-warning-container { + background-color: var(--accent-red); + color: white; + + .message { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + + a { + border: none; + color: inherit; + margin: 0; + padding: 0 .5em; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } +}