Avoid shadowing Python typing and retain pending mixed input selections
This commit is contained in:
1 parent
639cf3ee5e
commit
f28a652347
8 files changed
+41
-14
No files matched your search
@@ -14,7 +14,7 @@ fi
|
||||
|
||||
method=${1:-}
|
||||
if [[ -z $method ]]; then
|
||||
python "$OMARCHY_PATH/default/input-methods/typing.py" input
|
||||
python "$OMARCHY_PATH/default/input-methods/typing_setup.py" input
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
python "$OMARCHY_PATH/default/input-methods/typing.py" keyboard
|
||||
python "$OMARCHY_PATH/default/input-methods/typing_setup.py" keyboard
|
||||
@@ -114,12 +114,15 @@ class Indicator:
|
||||
def select_next(self):
|
||||
state = snapshot(self.bus)
|
||||
methods = state["methods"]
|
||||
if len(methods) < 2:
|
||||
state["current"] = self.pending or state["current"] or self.last or next(iter(methods), "")
|
||||
devices = subprocess.run(["hyprctl", "-j", "devices"], check=True, text=True, capture_output=True)
|
||||
keyboards = json.loads(devices.stdout).get("keyboards", [])
|
||||
following, index = cycle_choice(state, keyboards)
|
||||
if following is None:
|
||||
return
|
||||
current = self.pending or state["current"] or self.last or methods[0]
|
||||
if current not in methods:
|
||||
current = methods[0]
|
||||
self.pending = methods[(methods.index(current) + 1) % len(methods)]
|
||||
self.pending = following
|
||||
for command in layout_switches(keyboards, index) if index is not None else []:
|
||||
subprocess.run(command, check=True, capture_output=True)
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
|
||||
@@ -57,7 +57,7 @@ def choose(title, catalog, selected, kind, overrides=None):
|
||||
catalog = {**catalog, **{key: catalog.get(key, key) for key in selected}}
|
||||
rows = picker_rows(catalog, selected)
|
||||
args = ["omarchy-menu-select", title] + list(rows.values())
|
||||
on_change = ["python", str(setup.ROOT / "default/input-methods/typing.py"), "apply", kind, json.dumps({"catalog": catalog, "overrides": overrides or {}})]
|
||||
on_change = ["python", str(setup.ROOT / "default/input-methods/typing_setup.py"), "apply", kind, json.dumps({"catalog": catalog, "overrides": overrides or {}})]
|
||||
args += ["--", "--multiple", "--width", "620", "--maxheight", "650", "--on-change", json.dumps(on_change), "--change-key", "typing:" + kind]
|
||||
for key in selected:
|
||||
args += ["--selected", rows[key][1:]]
|
||||
@@ -10,7 +10,7 @@ The ISO carries the extra fields in `omarchy_install.input_method` and `omarchy_
|
||||
|
||||
`omarchy setup input <engine>` installs the selected engine, restarts the supervised Fcitx unit so it discovers new addons, and appends the engine through `InputMethodGroupInfo`, `SetInputMethodGroupInfo`, and `Save`. It keeps the group name, layout, existing methods, and their layout overrides. There is no parallel unsupervised daemon. A per-user D-Bus activation file delegates `org.fcitx.Fcitx5` to `omarchy-fcitx5.service`; it is loaded before live restart.
|
||||
|
||||
`Setup > Typing > Keyboard Layouts` and `Input Methods` use the native menu's multi-select mode, with current entries checked and changes applied immediately. `default/input-methods/typing.py` uses the installer’s keyboard choices, converted to desktop layouts through systemd’s keymap table, and reads the current input group. Input selection replaces only the non-keyboard group items and retains selected engines' layout overrides; deselection does not uninstall packages. The standard composition engines are already shipped in the base package set. Closing a picker keeps changes already applied. Failed updates leave its checked state unchanged.
|
||||
`Setup > Typing > Keyboard Layouts` and `Input Methods` use the native menu's multi-select mode, with current entries checked and changes applied immediately. `default/input-methods/typing_setup.py` uses the installer’s keyboard choices, converted to desktop layouts through systemd’s keymap table, and reads the current input group. Input selection replaces only the non-keyboard group items and retains selected engines' layout overrides; deselection does not uninstall packages. The standard composition engines are already shipped in the base package set. Closing a picker keeps changes already applied. Failed updates leave its checked state unchanged.
|
||||
|
||||
Keyboard selections are persisted as data in `~/.config/omarchy/keyboard-layouts`; `default.hypr.keyboard.selected()` reads them before falling back to installation defaults. Personal Hyprland overrides still take precedence. A save reloads and validates the compositor, aligns the Fcitx group's primary keyboard with the leading layout/variant, and restores the previous configuration and group on failure. Non-Latin selections keep the installer's Latin-leading rule for desktop shortcuts. System console, disk-unlock, and greeter layouts are unchanged.
|
||||
|
||||
|
||||
@@ -244,9 +244,7 @@ BarWidget {
|
||||
horizontalMargin: 6
|
||||
tooltipText: KeyboardLayoutModel.inputTooltip(root.inputState, root.layoutFull, root.multipleLayouts)
|
||||
onPressed: function(button) {
|
||||
if (root.multipleLayouts && button === Qt.LeftButton) {
|
||||
root.bar.run("omarchy-input-method cycle")
|
||||
} else if (root.multipleInputs && button === Qt.LeftButton) {
|
||||
if ((root.multipleInputs || root.multipleLayouts) && button === Qt.LeftButton) {
|
||||
InputMethodState.cycle()
|
||||
} else if (root.multipleLayouts) {
|
||||
root.cycleLayout()
|
||||
|
||||
@@ -10,6 +10,9 @@ from unittest.mock import patch
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
# Script-directory imports must not shadow Python's standard typing module.
|
||||
subprocess.run(["/usr/bin/python", "-c", "import sys; sys.path.insert(0, sys.argv[1]); import typing; from gi.repository import Gio; assert hasattr(typing, 'TYPE_CHECKING')", os.environ["OMARCHY_PATH"] + "/default/input-methods"], check=True)
|
||||
|
||||
spec = importlib.util.spec_from_file_location("indicator", os.environ["OMARCHY_PATH"] + "/default/input-methods/indicator.py")
|
||||
indicator = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(indicator)
|
||||
@@ -55,7 +58,7 @@ def fake_call(bus, method, args=None):
|
||||
return ()
|
||||
raise AssertionError(method)
|
||||
|
||||
with patch.object(indicator, "snapshot", side_effect=lambda bus: dict(live)), patch.object(indicator, "call", side_effect=fake_call):
|
||||
with patch.object(indicator, "snapshot", side_effect=lambda bus: dict(live)), patch.object(indicator, "call", side_effect=fake_call), patch.object(indicator.subprocess, "run", return_value=subprocess.CompletedProcess([], 0, stdout='{"keyboards": []}')):
|
||||
reader = indicator.Indicator(None)
|
||||
assert reader.refresh()["current"] == "keyboard-us"
|
||||
reader.select_next()
|
||||
@@ -127,4 +130,27 @@ with patch.object(indicator.Gio, "bus_get_sync", return_value=None), patch.objec
|
||||
assert all(command.args[0][-1] == "0" for command in process.call_args_list[1:])
|
||||
print("ok - layouts and composition engines share one cycle and returning to direct input resets the layout")
|
||||
|
||||
keyboards = [{"name": "physical", "layout": "us,dk", "active_layout_index": 0}]
|
||||
live = {"methods": ["keyboard-us", "pinyin"], "current": "", "name": "", "label": "", "language": ""}
|
||||
selected.clear()
|
||||
def fake_process(command, **kwargs):
|
||||
if command[:3] == ["hyprctl", "-j", "devices"]:
|
||||
return subprocess.CompletedProcess(command, 0, stdout=json.dumps({"keyboards": keyboards}))
|
||||
keyboards[0]["active_layout_index"] = int(command[-1])
|
||||
return subprocess.CompletedProcess(command, 0, stdout="")
|
||||
with patch.object(indicator, "snapshot", side_effect=lambda bus: dict(live)), patch.object(indicator, "call", side_effect=fake_call), patch.object(indicator.subprocess, "run", side_effect=fake_process):
|
||||
reader = indicator.Indicator(None)
|
||||
reader.select_next()
|
||||
assert keyboards[0]["active_layout_index"] == 1
|
||||
reader.select_next()
|
||||
assert reader.pending == "pinyin" and selected == []
|
||||
assert reader.refresh()["current"] == "pinyin"
|
||||
live["current"] = "keyboard-us"
|
||||
reader.refresh()
|
||||
assert selected == ["pinyin"] and reader.pending == ""
|
||||
reader.select_next()
|
||||
assert keyboards[0]["active_layout_index"] == 0
|
||||
assert selected[-1] == "keyboard-us"
|
||||
print("ok - mixed-layout bar clicks queue an engine without focus and apply it when a text field gains focus")
|
||||
|
||||
PY
|
||||
@@ -10,7 +10,7 @@ from unittest.mock import patch
|
||||
|
||||
ROOT = Path(os.environ["OMARCHY_PATH"])
|
||||
sys.path.insert(0, str(ROOT / "default/input-methods"))
|
||||
spec = importlib.util.spec_from_file_location("typing_setup", ROOT / "default/input-methods/typing.py")
|
||||
spec = importlib.util.spec_from_file_location("typing_setup", ROOT / "default/input-methods/typing_setup.py")
|
||||
typing = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(typing)
|
||||
|
||||
|
||||
Reference in new issue
Block a user