mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
parent
6eb1db0f5d
commit
469fd763c7
7 changed files with 61 additions and 17 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -3548,6 +3548,7 @@ dependencies = [
|
|||
"embed-resource",
|
||||
"libc",
|
||||
"libc-stdhandle",
|
||||
"widestring",
|
||||
"windows 0.61.3",
|
||||
]
|
||||
|
||||
|
@ -7375,6 +7376,12 @@ dependencies = [
|
|||
"winsafe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
@ -138,8 +138,9 @@ unic-ucd-category = "0.9.0"
|
|||
unicode-normalization = "0.1.24"
|
||||
walkdir = "2.5.0"
|
||||
which = "8.0.0"
|
||||
widestring = "1.1.0"
|
||||
winapi = { version = "0.3", features = ["wincon", "winreg"] }
|
||||
windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams", "Win32_System_Console", "Win32_System_Registry", "Win32_Foundation"] }
|
||||
windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams", "Win32_System_Console", "Win32_System_Registry", "Win32_Foundation", "Win32_UI_Shell"] }
|
||||
wiremock = "0.6.3"
|
||||
xz2 = "0.1.7"
|
||||
zip = { version = "4.1.0", default-features = false, features = ["deflate", "time"] }
|
||||
|
|
|
@ -42,6 +42,11 @@ if "--syncserver" in sys.argv:
|
|||
# does not return
|
||||
run_sync_server()
|
||||
|
||||
if sys.platform == "win32":
|
||||
from win32com.shell import shell
|
||||
|
||||
shell.SetCurrentProcessExplicitAppUserModelID("Ankitects.Anki")
|
||||
|
||||
import argparse
|
||||
import builtins
|
||||
import cProfile
|
||||
|
|
|
@ -1719,11 +1719,37 @@ title="{}" {}>{}</button>""".format(
|
|||
self.maybeHideAccelerators()
|
||||
self.hideStatusTips()
|
||||
elif is_win:
|
||||
# make sure ctypes is bundled
|
||||
from ctypes import windll, wintypes # type: ignore
|
||||
self._setupWin32()
|
||||
|
||||
_dummy1 = windll
|
||||
_dummy2 = wintypes
|
||||
def _setupWin32(self):
|
||||
"""Fix taskbar display/pinning"""
|
||||
if sys.platform != "win32":
|
||||
return
|
||||
|
||||
launcher_path = os.environ.get("ANKI_LAUNCHER")
|
||||
if not launcher_path:
|
||||
return
|
||||
|
||||
from win32com.propsys import propsys, pscon
|
||||
from win32com.propsys.propsys import PROPVARIANTType
|
||||
|
||||
hwnd = int(self.winId())
|
||||
prop_store = propsys.SHGetPropertyStoreForWindow(hwnd) # type: ignore[call-arg]
|
||||
prop_store.SetValue(
|
||||
pscon.PKEY_AppUserModel_ID, PROPVARIANTType("Ankitects.Anki")
|
||||
)
|
||||
prop_store.SetValue(
|
||||
pscon.PKEY_AppUserModel_RelaunchCommand,
|
||||
PROPVARIANTType(f'"{launcher_path}"'),
|
||||
)
|
||||
prop_store.SetValue(
|
||||
pscon.PKEY_AppUserModel_RelaunchDisplayNameResource, PROPVARIANTType("Anki")
|
||||
)
|
||||
prop_store.SetValue(
|
||||
pscon.PKEY_AppUserModel_RelaunchIconResource,
|
||||
PROPVARIANTType(f"{launcher_path},0"),
|
||||
)
|
||||
prop_store.Commit()
|
||||
|
||||
def maybeHideAccelerators(self, tgt: Any | None = None) -> None:
|
||||
if not self.hideMenuAccels:
|
||||
|
|
|
@ -16,6 +16,7 @@ dirs.workspace = true
|
|||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows.workspace = true
|
||||
widestring.workspace = true
|
||||
libc.workspace = true
|
||||
libc-stdhandle.workspace = true
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ pub fn respawn_launcher() -> Result<()> {
|
|||
pub fn launch_anki_normally(mut cmd: std::process::Command) -> Result<()> {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
crate::platform::windows::attach_to_parent_console();
|
||||
crate::platform::windows::prepare_to_launch_normally();
|
||||
cmd.ensure_success()?;
|
||||
}
|
||||
#[cfg(unix)]
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::io::stdin;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::process::Command;
|
||||
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use widestring::u16cstr;
|
||||
use windows::core::PCWSTR;
|
||||
use windows::Win32::System::Registry::HKEY_CURRENT_USER;
|
||||
use windows::Win32::System::Console::AttachConsole;
|
||||
use windows::Win32::System::Console::GetConsoleWindow;
|
||||
use windows::Win32::System::Console::ATTACH_PARENT_PROCESS;
|
||||
|
@ -17,8 +15,10 @@ use windows::Win32::System::Registry::RegCloseKey;
|
|||
use windows::Win32::System::Registry::RegOpenKeyExW;
|
||||
use windows::Win32::System::Registry::RegQueryValueExW;
|
||||
use windows::Win32::System::Registry::HKEY;
|
||||
use windows::Win32::System::Registry::HKEY_CURRENT_USER;
|
||||
use windows::Win32::System::Registry::KEY_READ;
|
||||
use windows::Win32::System::Registry::REG_SZ;
|
||||
use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID;
|
||||
|
||||
pub fn ensure_terminal_shown() -> Result<()> {
|
||||
unsafe {
|
||||
|
@ -146,10 +146,7 @@ fn read_registry_install_dir() -> Option<std::path::PathBuf> {
|
|||
let mut hkey = HKEY::default();
|
||||
|
||||
// Convert the registry path to wide string
|
||||
let subkey: Vec<u16> = OsStr::new("SOFTWARE\\Anki")
|
||||
.encode_wide()
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
let subkey = u16cstr!("SOFTWARE\\Anki");
|
||||
|
||||
// Open the registry key
|
||||
let result = RegOpenKeyExW(
|
||||
|
@ -165,10 +162,7 @@ fn read_registry_install_dir() -> Option<std::path::PathBuf> {
|
|||
}
|
||||
|
||||
// Query the Install_Dir64 value
|
||||
let value_name: Vec<u16> = OsStr::new("Install_Dir64")
|
||||
.encode_wide()
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
let value_name = u16cstr!("Install_Dir64");
|
||||
|
||||
let mut value_type = REG_SZ;
|
||||
let mut data_size = 0u32;
|
||||
|
@ -211,3 +205,13 @@ fn read_registry_install_dir() -> Option<std::path::PathBuf> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prepare_to_launch_normally() {
|
||||
// Set the App User Model ID for Windows taskbar grouping
|
||||
unsafe {
|
||||
let _ =
|
||||
SetCurrentProcessExplicitAppUserModelID(PCWSTR(u16cstr!("Ankitects.Anki").as_ptr()));
|
||||
}
|
||||
|
||||
attach_to_parent_console();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue