omarchy-ui 0.0.6-x86_64-linux → 0.0.7-x86_64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c8e67a6ee733ab185881c3af8614d428d5888fcea3fed015780ccc4bae6a3b5
4
- data.tar.gz: 648c98f47aea9d30e857809a65052bdb2ca374ecaebc122a3ea192b99aa2b815
3
+ metadata.gz: d389e6d9a8382cb8feec3a900ce2b4ee14001d214a069e96be8e7567e549f39e
4
+ data.tar.gz: 77d33296ea0cc16f08a93bb94a17607a3b50d19e036f2649304a89fcc4b9f455
5
5
  SHA512:
6
- metadata.gz: 5f7664f1dafd992a22872bc029e8c48a242452ad5a8df9185a2aa0707b94b14df8724bd2e8c4fe3bd79afedeaf957e838fb1e27ecabb9467ba0ec41806e8f6d8
7
- data.tar.gz: 97ec7a87a20e40653d8247cf69fd2534febb44b89ea7601355ada885d5f1978753332418ae756c9cf2e934a5534d108f43a850eca1c2ef3dc1c741435243d4ea
6
+ metadata.gz: 2be91201712539398abbf26b03cc3298947d2ff040da32e7171009ef70fdb4127adb7ab5992088176a5f28d5f901cdf4bcdfec68e65c13123bcb3fc61c2206f7
7
+ data.tar.gz: 89953562fbc3a943290234a297e5cd0f6ecf98b9f7b17a9188a5072716cf42e39e7281c724b97d2b4926df7aabd973485dbbc012ad3285447aaf36de9a7f5514
data/App.qml CHANGED
@@ -2,6 +2,7 @@ import QtQuick
2
2
  import Quickshell
3
3
  import qs.Commons
4
4
  import qs.Ui as OmarchyUi
5
+ import "Theme" as ZuiTheme
5
6
 
6
7
  ShellRoot {
7
8
  id: root
@@ -82,7 +83,7 @@ ShellRoot {
82
83
  }
83
84
  }
84
85
 
85
- ZuiRenderer {
86
+ ControlNode {
86
87
  id: renderer
87
88
  anchors {
88
89
  left: parent.left
@@ -91,7 +92,7 @@ ShellRoot {
91
92
  bottom: parent.bottom
92
93
  margins: Style.space(24)
93
94
  }
94
- visible: renderReady
95
+ visible: ZuiTheme.Fonts.ready && root.activeSurface !== "" && service.rootId(root.activeSurface) !== ""
95
96
  bridge: service
96
97
  surfaceName: root.activeSurface
97
98
  controlId: service.rootId(surfaceName)
@@ -103,7 +104,7 @@ ShellRoot {
103
104
  anchors.centerIn: parent
104
105
  visible: !renderer.visible
105
106
  text: service.lastError !== "" ? service.lastError
106
- : "Starting Ruby UI with Zui…"
107
+ : (ZuiTheme.Fonts.failed ? "Omarchy UI could not load Zui's bundled fonts" : "Starting Ruby UI…")
107
108
  color: Color.foreground
108
109
  font.family: Style.font.family
109
110
  font.pixelSize: Style.font.body
data/BarWidget.qml CHANGED
@@ -1,6 +1,7 @@
1
1
  import QtQuick
2
2
  import qs.Commons
3
3
  import qs.Ui
4
+ import "Theme" as ZuiTheme
4
5
 
5
6
  BarWidget {
6
7
  id: root
@@ -16,10 +17,10 @@ BarWidget {
16
17
  implicitWidth: Math.max(Style.bar.iconSlot, renderer.implicitWidth + Style.space(12))
17
18
  implicitHeight: barSize
18
19
 
19
- ZuiRenderer {
20
+ ControlNode {
20
21
  id: renderer
21
22
  anchors.centerIn: parent
22
- visible: renderReady
23
+ visible: ZuiTheme.Fonts.ready && root.rubyService && root.rootControlId !== ""
23
24
  bridge: root.rubyService
24
25
  surfaceName: root.surfaceName
25
26
  controlId: root.rootControlId
data/Panel.qml CHANGED
@@ -3,6 +3,7 @@ import Quickshell
3
3
  import Quickshell.Wayland
4
4
  import qs.Commons
5
5
  import qs.Ui as OmarchyUi
6
+ import "Theme" as ZuiTheme
6
7
 
7
8
  Item {
8
9
  id: root
@@ -77,10 +78,10 @@ Item {
77
78
  onClicked: {}
78
79
  }
79
80
 
80
- ZuiRenderer {
81
+ ControlNode {
81
82
  id: renderer
82
83
  anchors.centerIn: parent
83
- visible: renderReady
84
+ visible: ZuiTheme.Fonts.ready && root.service && root.rootControlId !== ""
84
85
  bridge: root.service
85
86
  surfaceName: root.surfaceName
86
87
  controlId: root.rootControlId
@@ -97,7 +98,7 @@ Item {
97
98
  anchors.horizontalCenter: parent.horizontalCenter
98
99
  text: root.service && root.service.lastError !== ""
99
100
  ? root.service.lastError
100
- : "Starting Ruby UI with Zui…"
101
+ : (ZuiTheme.Fonts.failed ? "Omarchy UI could not load Zui's bundled fonts" : "Starting Ruby UI…")
101
102
  color: Color.foreground
102
103
  font.family: Style.font.family
103
104
  font.pixelSize: Style.font.body
data/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  </p>
11
11
 
12
12
  <p align="center">
13
- <img alt="Omarchy UI 0.0.6" src="https://img.shields.io/badge/Omarchy_UI-0.0.6-b7ff5a?style=flat-square&labelColor=111711">
13
+ <img alt="Omarchy UI 0.0.7" src="https://img.shields.io/badge/Omarchy_UI-0.0.7-b7ff5a?style=flat-square&labelColor=111711">
14
14
  <img alt="Ruby 3.1 or newer" src="https://img.shields.io/badge/Ruby-3.1%2B-cc342d?style=flat-square&logo=ruby&logoColor=white">
15
15
  <img alt="Zui 0.0.10" src="https://img.shields.io/badge/Zui-0.0.10-7ee14b?style=flat-square&labelColor=111711">
16
16
  <img alt="241 components" src="https://img.shields.io/badge/components-241-75d943?style=flat-square&labelColor=111711">
@@ -63,11 +63,10 @@ and the Omarchy adapter.
63
63
  - Ruby 3.1 or newer while installing the gem and developing applications;
64
64
  - optional Qt modules for components that use features such as Quick 3D or Multimedia.
65
65
 
66
- The finished Omarchy bundle includes the Omarchy adapter and mruby executable. Shared renderers,
67
- controls, theme, and fonts stay in the compatible Zui gem instead of being duplicated into every
68
- plugin. The destination therefore needs Ruby and `omarchy-ui` installed. A component fails with an
69
- explicit error when its gem, required Qt module, or resource is unavailable; Omarchy UI never
70
- substitutes a different component.
66
+ The finished Omarchy bundle includes the Omarchy adapter, mruby executable, and a Zui-generated QML
67
+ runtime tree-shaken to the components referenced by that application. The destination does not need
68
+ Ruby or framework gems. A component fails with an explicit error when its required Qt module or
69
+ resource is unavailable; Omarchy UI never substitutes a different component.
71
70
 
72
71
  ## Quick start
73
72
 
@@ -103,7 +102,7 @@ counter/
103
102
  omarchy_ui run main.rb
104
103
  ```
105
104
 
106
- `run` bundles the project's Ruby entry point, prepares the Omarchy host, resolves the exact Zui gem,
105
+ `run` bundles the project's Ruby entry point, asks Zui to tree-shake the QML runtime, prepares the Omarchy host,
107
106
  then launches it through Quickshell.
108
107
 
109
108
  ## Application model
@@ -335,7 +334,7 @@ omarchy_ui <command> [arguments]
335
334
  | --- | --- | --- |
336
335
  | `omarchy_ui new NAME` | One application name | Creates a new application directory using a URL-safe form of the name |
337
336
  | `omarchy_ui run FILE` | One Ruby entry point | Runs an application through the Omarchy/Quickshell host |
338
- | `omarchy_ui bundle [DIRECTORY]` | Zero or one project directory | Creates `dist/<project-name>` with the application, Omarchy adapter, and runtime; shared UI comes from Zui |
337
+ | `omarchy_ui bundle [DIRECTORY]` | Zero or one project directory | Creates `dist/<project-name>` with the application, Omarchy adapter, runtime, and tree-shaken Zui QML |
339
338
  | `omarchy_ui validate [DIRECTORY]` | Zero or one plugin directory | Stages the complete plugin and delegates validation to `omarchy plugin validate` |
340
339
  | `omarchy_ui push [DIRECTORY]` | Optional `--no-enable` and `--no-restart` | Atomically installs and activates a validated plugin |
341
340
  | `omarchy_ui version` | None | Prints the installed Omarchy UI version |
@@ -362,7 +361,10 @@ dist/my-application/
362
361
  ├── Service.qml # process and surface bridge
363
362
  ├── Panel.qml # shell panel adapter
364
363
  ├── BarWidget.qml # shell bar adapter
365
- ├── ZuiRenderer.qml # resolves Zui's shared protocol renderer
364
+ ├── ControlNode.qml # generated Zui protocol renderer
365
+ ├── Components/Builtins/ # only component adapters selected by Zui
366
+ ├── Controls/ Theme/ Fonts/ # generated renderer dependencies
367
+ ├── zui-tree-shake.json # auditable selected-component report
366
368
  ├── Commons@ Ui@ # links to Omarchy's shell modules
367
369
  ├── omarchy-ui-runtime # embedded mruby executable
368
370
  ├── omarchy-ui-runtime.sha256
@@ -371,10 +373,9 @@ dist/my-application/
371
373
  ```
372
374
 
373
375
  Plugin bundles use the same runtime package and are validated against their manifest before the
374
- bundle command succeeds. Generated packages exclude `.git`, previous `dist` output, stale
375
- adapter/runtime files, and every Zui-owned QML directory. Install `omarchy-ui` on the destination so
376
- RubyGems supplies the exact Zui 0.0.10 catalog once for every plugin. The exact pin intentionally
377
- matches the Zui core embedded in the deterministic mruby runtime.
376
+ bundle command succeeds. Generated packages exclude `.git`, previous `dist` output, and stale
377
+ adapter/runtime files before regenerating the minimal QML package. Omarchy UI pins Zui 0.0.10 so the
378
+ tree-shaken QML exactly matches the Zui core embedded in the deterministic mruby runtime.
378
379
 
379
380
  ## Component catalog
380
381
 
@@ -461,10 +462,10 @@ The dependency direction is deliberate:
461
462
  integration, plugin lifecycle commands, and Omarchy packaging.
462
463
  - **Applications own** Ruby source, assets, state, behavior, and reusable UI modules.
463
464
 
464
- At runtime, the adapter locates the compatible Zui gem and loads its protocol renderer, components,
465
- controls, theme, and fonts directly from `Zui::FRAMEWORK_ROOT`. Bundle, validation, and push install
466
- only the Omarchy host files and never copy Zui component implementations into an application or
467
- plugin. Read the full [QML ownership and adapter boundary](docs/qml-support.md).
465
+ At bundle, validation, and push time, Omarchy UI asks Zui to analyze the bundled Ruby syntax and
466
+ generate only the required component adapters plus their renderer dependencies. The four Omarchy
467
+ host files then replace Zui's generic desktop host. Read the full [QML ownership and adapter
468
+ boundary](docs/qml-support.md).
468
469
 
469
470
  ## Runtime integrity
470
471
 
data/Service.qml CHANGED
@@ -14,11 +14,6 @@ Item {
14
14
  readonly property string rubyProgram: pluginDir + "/main.rb"
15
15
  property string program: ""
16
16
  readonly property string effectiveRubyProgram: program !== "" ? program : rubyProgram
17
- readonly property string requiredZuiVersion: "0.0.10"
18
- property string zuiRoot: ""
19
- property string zuiVersion: ""
20
- readonly property bool zuiReady: zuiRoot !== ""
21
-
22
17
  property bool ready: false
23
18
  property bool stopping: false
24
19
  property string lastError: ""
@@ -418,7 +413,7 @@ Item {
418
413
 
419
414
  function componentSource(typeName) {
420
415
  var definition = componentDefinitions[String(typeName || "")]
421
- return definition && zuiReady ? zuiRoot + "/Components/Builtins/" + definition.qml : ""
416
+ return definition ? pluginDir + "/Components/Builtins/" + definition.qml : ""
422
417
  }
423
418
 
424
419
  function componentDefinition(typeName) {
@@ -446,7 +441,7 @@ Item {
446
441
  }
447
442
 
448
443
  function startRuby() {
449
- if (stopping || pluginDir === "" || !zuiReady || rubyProcess.running) return
444
+ if (stopping || pluginDir === "" || rubyProcess.running) return
450
445
  var configuredRuntime = String(Quickshell.env("OMARCHY_UI_RUNTIME") || "")
451
446
  rubyProcess.command = [
452
447
  configuredRuntime !== "" ? configuredRuntime : pluginDir + "/omarchy-ui-runtime",
@@ -456,68 +451,14 @@ Item {
456
451
  rubyProcess.running = true
457
452
  }
458
453
 
459
- function locateZui() {
460
- if (stopping || pluginDir === "" || zuiReady || zuiLocator.running) return
461
- zuiLocator.command = [
462
- "ruby", "-e",
463
- 'require "json"; gem "zui", "= ' + requiredZuiVersion
464
- + '"; require "zui"; STDOUT.write(JSON.generate({root: Zui::FRAMEWORK_ROOT, version: Zui::VERSION}))'
465
- ]
466
- zuiLocator.running = true
467
- }
468
-
469
- onPluginDirChanged: {
470
- zuiRoot = ""
471
- zuiVersion = ""
472
- Qt.callLater(locateZui)
473
- }
474
-
475
- Component.onCompleted: Qt.callLater(locateZui)
454
+ onPluginDirChanged: Qt.callLater(startRuby)
476
455
 
477
456
  Component.onDestruction: {
478
457
  stopping = true
479
458
  restartTimer.stop()
480
- if (zuiLocator.running) zuiLocator.running = false
481
459
  if (rubyProcess.running) rubyProcess.running = false
482
460
  }
483
461
 
484
- Process {
485
- id: zuiLocator
486
-
487
- stdout: StdioCollector {
488
- id: zuiLocatorOutput
489
- waitForEnd: true
490
- }
491
-
492
- stderr: StdioCollector {
493
- id: zuiLocatorError
494
- waitForEnd: true
495
- }
496
-
497
- onExited: function(exitCode) {
498
- if (root.stopping || root.pluginDir === "") return
499
- var detail = String(zuiLocatorError.text || "").trim()
500
- if (exitCode !== 0) {
501
- root.lastError = "Zui " + root.requiredZuiVersion
502
- + " is required from the omarchy-ui gem"
503
- + (detail !== "" ? ": " + detail.slice(0, 240) : "")
504
- return
505
- }
506
- try {
507
- var located = JSON.parse(String(zuiLocatorOutput.text || ""))
508
- if (!located || typeof located.root !== "string" || located.root[0] !== "/"
509
- || String(located.version || "") !== root.requiredZuiVersion)
510
- throw new Error("invalid Zui gem location")
511
- root.zuiRoot = String(located.root)
512
- root.zuiVersion = String(located.version)
513
- root.lastError = ""
514
- root.startRuby()
515
- } catch (error) {
516
- root.lastError = "Could not locate Zui " + root.requiredZuiVersion + " from RubyGems"
517
- }
518
- }
519
- }
520
-
521
462
  Process {
522
463
  id: rubyProcess
523
464
  stdinEnabled: true
@@ -1,19 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
+ require "json"
5
+ require "tmpdir"
4
6
 
5
7
  module OmarchyUI
6
8
  module Runtime
7
9
  module_function
8
10
 
9
11
  BUNDLED = File.expand_path("../../vendor/runtime/x86_64-linux/omarchy-ui-runtime", __dir__)
10
- ADAPTER_FILES = %w[Service.qml Panel.qml BarWidget.qml App.qml ZuiRenderer.qml].freeze
12
+ ADAPTER_FILES = %w[Service.qml Panel.qml BarWidget.qml App.qml].freeze
11
13
  ZUI_GENERATED_ENTRIES = %w[Desktop.qml ControlNode.qml Components Controls Theme Fonts].freeze
12
- FILES = ADAPTER_FILES.freeze
14
+ TREE_SHAKE_REPORT = "zui-tree-shake.json"
15
+ FILES = (ADAPTER_FILES + %w[ControlNode.qml]).freeze
13
16
  AUDIT_FILES = %w[
14
17
  omarchy-ui-runtime.sha256 runtime-provenance.json RUNTIME_PROVENANCE.md
15
18
  ].freeze
16
- GENERATED_ENTRIES = (ADAPTER_FILES + ZUI_GENERATED_ENTRIES + %w[omarchy-ui-runtime]).freeze
19
+ GENERATED_ENTRIES = (ADAPTER_FILES + ZUI_GENERATED_ENTRIES +
20
+ [TREE_SHAKE_REPORT, "omarchy-ui-runtime"]).freeze
17
21
 
18
22
  def executable
19
23
  override = ENV["OMARCHY_UI_RUNTIME"]
@@ -35,15 +39,24 @@ module OmarchyUI
35
39
  FileUtils.rm_f(temporary) if temporary && File.exist?(temporary)
36
40
  end
37
41
 
38
- def install_package(path, framework_root: FRAMEWORK_ROOT)
42
+ def install_package(path, framework_root: FRAMEWORK_ROOT, project: path)
39
43
  FileUtils.mkdir_p(path)
40
- ZUI_GENERATED_ENTRIES.each do |entry|
44
+ GENERATED_ENTRIES.each do |entry|
41
45
  generated = File.join(path, entry)
42
46
  File.directory?(generated) ? FileUtils.remove_entry(generated) : FileUtils.rm_f(generated)
43
47
  end
48
+ report = install_tree_shaken_zui(path, project:)
44
49
  ADAPTER_FILES.each do |file|
45
50
  FileUtils.cp(File.join(framework_root, file), File.join(path, file))
46
51
  end
52
+ File.write(File.join(path, TREE_SHAKE_REPORT), JSON.pretty_generate({
53
+ "zui_version" => Zui::VERSION,
54
+ "components" => report.components.map(&:to_s),
55
+ "before_bytes" => report.before_bytes,
56
+ "after_bytes" => report.after_bytes,
57
+ "saved_bytes" => report.saved_bytes,
58
+ "warnings" => report.warnings
59
+ }) + "\n")
47
60
 
48
61
  if File.file?(BUNDLED)
49
62
  destination = File.join(path, "omarchy-ui-runtime")
@@ -57,8 +70,22 @@ module OmarchyUI
57
70
  path
58
71
  end
59
72
 
60
- def install_components(path, **)
61
- install_package(path)
73
+ def install_components(path, **options)
74
+ install_package(path, **options)
75
+ end
76
+
77
+ def install_tree_shaken_zui(destination, project:)
78
+ Dir.mktmpdir("omarchy-ui-zui-") do |temporary|
79
+ qml = File.join(temporary, "qml")
80
+ native = File.join(temporary, "native")
81
+ FileUtils.mkdir_p(native)
82
+ Zui::Runtime.install_qml(qml)
83
+ report = Zui::TreeShaker.new(project:, framework: qml, native:).shake!
84
+ FileUtils.rm_f([File.join(qml, "Desktop.qml"), File.join(qml, "Service.qml")])
85
+ entries = Dir.children(qml).map { |entry| File.join(qml, entry) }
86
+ FileUtils.cp_r(entries, destination) unless entries.empty?
87
+ return report
88
+ end
62
89
  end
63
90
  end
64
91
  end
data/lib/omarchy_ui.rb CHANGED
@@ -11,7 +11,7 @@ rescue LoadError
11
11
  end
12
12
 
13
13
  module OmarchyUI
14
- VERSION = "0.0.6"
14
+ VERSION = "0.0.7"
15
15
  ZUI_VERSION = Zui::VERSION
16
16
  FRAMEWORK_ROOT = File.expand_path("..", __dir__)
17
17
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omarchy-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Adam Moussa Ali
@@ -35,7 +35,6 @@ files:
35
35
  - Panel.qml
36
36
  - README.md
37
37
  - Service.qml
38
- - ZuiRenderer.qml
39
38
  - bin/omarchy_ui
40
39
  - lib/omarchy_ui.rb
41
40
  - lib/omarchy_ui/cli.rb
data/ZuiRenderer.qml DELETED
@@ -1,37 +0,0 @@
1
- import QtQuick
2
-
3
- Loader {
4
- id: root
5
-
6
- property var bridge: null
7
- property string surfaceName: ""
8
- property string controlId: ""
9
- property color foreground: "white"
10
- property string fontFamily: ""
11
- readonly property bool renderReady: status === Loader.Ready && item !== null
12
- && String(item.iconFontFamily || "") !== ""
13
- && String(item.brandIconFontFamily || "") !== ""
14
-
15
- active: bridge !== null && bridge.zuiReady && controlId !== ""
16
- source: active ? bridge.zuiRoot + "/ControlNode.qml" : ""
17
-
18
- function syncRenderer() {
19
- if (!item) return
20
- item.bridge = bridge
21
- item.surfaceName = surfaceName
22
- item.controlId = controlId
23
- item.foreground = foreground
24
- item.fontFamily = fontFamily
25
- }
26
-
27
- onLoaded: syncRenderer()
28
- onBridgeChanged: syncRenderer()
29
- onSurfaceNameChanged: syncRenderer()
30
- onControlIdChanged: syncRenderer()
31
- onForegroundChanged: syncRenderer()
32
- onFontFamilyChanged: syncRenderer()
33
- onStatusChanged: {
34
- if (status === Loader.Error && bridge)
35
- bridge.lastError = "Could not load Zui " + bridge.requiredZuiVersion + " renderer from its gem"
36
- }
37
- }