feat(identity): rename user-visible identity to voculinux with one-time legacy import

The fork takes its own name everywhere a user can see it: binaries
(voculinux, voculinux-gui), desktop entry, autostart, tray, D-Bus
namespace (com.voculinux.Voculinux, no alias for the old name),
config/data/cache dirs, single-instance lock, IBus engine identity,
tray icons, resource prefixes, VOCULINUX_* environment names, and the
update-checker user agent. The internal Python module stays vocalinux
and the distribution metadata keeps the upstream URLs as provenance.

On first run a previous Vocalinux install's config.json, custom
dictionary, and portal restore token are copied once into the new
locations (new config always wins, no merge, no write-back); models
re-resolve through the pinned-checksum download path. An offline
naming-sweep test proves no old-name strings remain on user-visible
surfaces outside the allowlist.

Refs #18
This commit is contained in:
soubarnak
2026-11-06 01:29:39 +05:30
parent c565e6d946
commit ea7be5f111
251 changed files with 2449 additions and 1991 deletions
+22 -22
View File
@@ -111,7 +111,7 @@ class TestDetectEnvironment(unittest.TestCase):
obj = _make_injector(DesktopEnvironment.X11)
env = {
"FLATPAK_ID": "com.vocalinux.Vocalinux",
"FLATPAK_ID": "com.voculinux.Voculinux",
"XDG_SESSION_TYPE": "wayland",
"DISPLAY": ":0",
}
@@ -126,7 +126,7 @@ class TestDetectEnvironment(unittest.TestCase):
obj = _make_injector(DesktopEnvironment.X11)
env = {
"FLATPAK_ID": "com.vocalinux.Vocalinux",
"FLATPAK_ID": "com.voculinux.Voculinux",
"XDG_SESSION_TYPE": "wayland",
"DISPLAY": ":0",
}
@@ -140,7 +140,7 @@ class TestDetectEnvironment(unittest.TestCase):
obj = _make_injector(DesktopEnvironment.WAYLAND)
env = {
"FLATPAK_ID": "com.vocalinux.Vocalinux",
"FLATPAK_ID": "com.voculinux.Voculinux",
"XDG_SESSION_TYPE": "wayland",
"WAYLAND_DISPLAY": "wayland-0",
"DISPLAY": ":0",
@@ -346,7 +346,7 @@ class TestCheckDependencies(unittest.TestCase):
mock_ibus_class.assert_called_once()
def test_force_backend_wtype_skips_ibus(self):
"""VOCALINUX_FORCE_BACKEND=wtype pins wtype even where IBus would be chosen."""
"""VOCULINUX_FORCE_BACKEND=wtype pins wtype even where IBus would be chosen."""
from vocalinux.text_injection.text_injector import DesktopEnvironment
obj = _make_injector(DesktopEnvironment.WAYLAND)
@@ -354,7 +354,7 @@ class TestCheckDependencies(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "wayland", "VOCALINUX_FORCE_BACKEND": "wtype"},
{"XDG_SESSION_TYPE": "wayland", "VOCULINUX_FORCE_BACKEND": "wtype"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.is_ibus_available", return_value=True),
@@ -450,7 +450,7 @@ class TestCheckDependencies(unittest.TestCase):
run(pinned).assert_not_called()
def test_explicit_auto_environment_ignores_the_saved_config_pin(self):
"""VOCALINUX_FORCE_BACKEND=auto is how you get one run of plain autodetection.
"""VOCULINUX_FORCE_BACKEND=auto is how you get one run of plain autodetection.
The resolver already knows an explicit auto from an unset variable; this
drives the whole of _check_dependencies to show the saved pin really is
@@ -467,7 +467,7 @@ class TestCheckDependencies(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "wayland", "VOCALINUX_FORCE_BACKEND": "auto"},
{"XDG_SESSION_TYPE": "wayland", "VOCULINUX_FORCE_BACKEND": "auto"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.config_dir", return_value="/fake/config"),
@@ -512,7 +512,7 @@ class TestCheckDependencies(unittest.TestCase):
"XDG_CURRENT_DESKTOP": desktop,
}
if not config_pin:
environ["VOCALINUX_FORCE_BACKEND"] = "ibus"
environ["VOCULINUX_FORCE_BACKEND"] = "ibus"
with (
patch.dict(
@@ -628,7 +628,7 @@ class TestCheckDependencies(unittest.TestCase):
"XDG_CURRENT_DESKTOP": "Hyprland",
}
if pin:
environ["VOCALINUX_FORCE_BACKEND"] = pin
environ["VOCULINUX_FORCE_BACKEND"] = pin
with (
patch.dict(os.environ, environ, clear=True),
patch(
@@ -716,7 +716,7 @@ class TestCheckDependencies(unittest.TestCase):
self.assertFalse(self._not_applied(output))
def test_pinned_log_line_names_the_config_source_not_the_variable(self):
"""A config-sourced pin must not be reported as VOCALINUX_FORCE_BACKEND."""
"""A config-sourced pin must not be reported as VOCULINUX_FORCE_BACKEND."""
from vocalinux.text_injection.text_injector import DesktopEnvironment, TextInjector
obj = _make_injector(DesktopEnvironment.WAYLAND)
@@ -736,7 +736,7 @@ class TestCheckDependencies(unittest.TestCase):
pinned_lines = [line for line in logs.output if "wtype" in line and "=" in line]
self.assertTrue(pinned_lines)
self.assertFalse(
[line for line in pinned_lines if "VOCALINUX_FORCE_BACKEND" in line],
[line for line in pinned_lines if "VOCULINUX_FORCE_BACKEND" in line],
f"config-sourced pin reported as the env var: {pinned_lines}",
)
@@ -764,7 +764,7 @@ class TestCheckDependencies(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "wayland", "VOCALINUX_FORCE_BACKEND": "ibus"},
{"XDG_SESSION_TYPE": "wayland", "VOCULINUX_FORCE_BACKEND": "ibus"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.is_ibus_available", return_value=True),
@@ -864,7 +864,7 @@ class TestCheckDependencies(unittest.TestCase):
)
def test_force_backend_ydotool_skips_ibus_and_wtype(self):
"""VOCALINUX_FORCE_BACKEND=ydotool pins ydotool even when wtype is available."""
"""VOCULINUX_FORCE_BACKEND=ydotool pins ydotool even when wtype is available."""
from vocalinux.text_injection.text_injector import DesktopEnvironment
obj = _make_injector(DesktopEnvironment.WAYLAND)
@@ -872,7 +872,7 @@ class TestCheckDependencies(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "wayland", "VOCALINUX_FORCE_BACKEND": "ydotool"},
{"XDG_SESSION_TYPE": "wayland", "VOCULINUX_FORCE_BACKEND": "ydotool"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.is_ibus_available", return_value=True),
@@ -890,7 +890,7 @@ class TestCheckDependencies(unittest.TestCase):
mock_ibus_class.assert_not_called()
def test_force_backend_ibus_bypasses_reachability_guards(self):
"""VOCALINUX_FORCE_BACKEND=ibus selects IBus even on an unbridged compositor."""
"""VOCULINUX_FORCE_BACKEND=ibus selects IBus even on an unbridged compositor."""
from vocalinux.text_injection.text_injector import DesktopEnvironment, TextInjector
obj = _make_injector(DesktopEnvironment.WAYLAND)
@@ -901,7 +901,7 @@ class TestCheckDependencies(unittest.TestCase):
{
"XDG_SESSION_TYPE": "wayland",
"XDG_CURRENT_DESKTOP": "Hyprland",
"VOCALINUX_FORCE_BACKEND": "ibus",
"VOCULINUX_FORCE_BACKEND": "ibus",
},
clear=True,
),
@@ -1596,7 +1596,7 @@ class TestPressBackspace(unittest.TestCase):
def test_ydotool_v1_uses_keycode_14(self):
obj = _make_backspace_injector("WAYLAND", tool="ydotool", legacy=False)
with patch.dict(os.environ, {"VOCALINUX_YDOTOOL_KEY_DELAY": "2"}):
with patch.dict(os.environ, {"VOCULINUX_YDOTOOL_KEY_DELAY": "2"}):
with patch("subprocess.run") as mock_run:
self.assertTrue(obj.press_backspace(2))
self.assertEqual(
@@ -1788,7 +1788,7 @@ class TestBackgroundIBusInitialization(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "x11", "VOCALINUX_FORCE_BACKEND": "ibus"},
{"XDG_SESSION_TYPE": "x11", "VOCULINUX_FORCE_BACKEND": "ibus"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.is_ibus_available", return_value=True),
@@ -1832,7 +1832,7 @@ class TestBackgroundIBusInitialization(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "wayland", "VOCALINUX_FORCE_BACKEND": "ibus"},
{"XDG_SESSION_TYPE": "wayland", "VOCULINUX_FORCE_BACKEND": "ibus"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.is_ibus_available", return_value=True),
@@ -1872,7 +1872,7 @@ class TestBackgroundIBusInitialization(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "x11", "VOCALINUX_FORCE_BACKEND": "ibus"},
{"XDG_SESSION_TYPE": "x11", "VOCULINUX_FORCE_BACKEND": "ibus"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.is_ibus_available", return_value=True),
@@ -1905,7 +1905,7 @@ class TestBackgroundIBusInitialization(unittest.TestCase):
with (
patch.dict(
os.environ,
{"XDG_SESSION_TYPE": "x11", "VOCALINUX_FORCE_BACKEND": "ibus"},
{"XDG_SESSION_TYPE": "x11", "VOCULINUX_FORCE_BACKEND": "ibus"},
clear=True,
),
patch("vocalinux.text_injection.text_injector.is_ibus_available", return_value=True),
@@ -1939,7 +1939,7 @@ class TestBackgroundIBusInitialization(unittest.TestCase):
obj._ibus_injector = MagicMock()
obj.wayland_tool = "ydotool"
obj._ibus_injector.prepare_engine.side_effect = RuntimeError("late failure")
obj._backend_pin = ("ibus", "VOCALINUX_FORCE_BACKEND")
obj._backend_pin = ("ibus", "VOCULINUX_FORCE_BACKEND")
with self.assertLogs("vocalinux.text_injection.text_injector", level="DEBUG") as logs:
obj._warn_if_pin_not_honoured(*obj._backend_pin)