plac

Unofficial Roon clients

Commits at 3b0a3dc94dd911d80d06d08409cc501552e3c29c

  1. 3b0a3dc9 core: Expose disconnect function Shota FUJI authored at Shota FUJI comitted at
  2. cf516079 macos: Accept Xcode project settings recommendation It has been showing a warning and it was annoying. Shota FUJI authored at Shota FUJI comitted at
  3. 1dd7aab4 macos: Change non-modified variable to immutable Addressed a Xcode warning. Shota FUJI authored at Shota FUJI comitted at
  4. afb2d6b4 macos: Merge server discovery and main window The former is (most of the case) shown once. The reason I changed the payload of ".found" case is, without that, the only reference will be "ConnectedView" and every updates to the View would release then re-create a connection. Shota FUJI authored at Shota FUJI comitted at
  5. d53ccec3 macos: Save connected server ID and reconnect on launch The current UX is not complete, as there is no way to disconnect. Considering the usecase of connecting to more than one Roon server is rare, the discovery window should be integrated into the main window. Then it can conditionally render server discovery or connected view without going to discovery view first. Shota FUJI authored at Shota FUJI comitted at
  6. 37c16ed0 core: Allow clients to set custom extension ID/name/version It has been pain to manage authorization tokens in Roon settings page. Shota FUJI authored at Shota FUJI comitted at
  7. dfc4cec0 macos: Display loading UI during extension authorization It has been unclear what it's doing and what a user should do. Shota FUJI authored at Shota FUJI comitted at
  8. 2bb754a9 macos: Polish PlaybackBar It was bit odd. Shota FUJI authored at Shota FUJI comitted at
  9. 8b8802c2 macos: Display now playing texts (title and artist, mostly) Shota FUJI authored at Shota FUJI comitted at
  10. 9e6bf7bf macos: Fix more than one element in array crashes application I don't know how I got to that iteration code, but the `UnsafePointer<T>.successor` is NOT a method to iterate over an array. <https://codeberg.org/pocka/plac/issues/17> Shota FUJI authored at Shota FUJI comitted at
  11. c972d09c macos: Fix app crash when server scan found nothing Shota FUJI authored at Shota FUJI comitted at
  12. 065d06d6 core: Print debug log on macOS build Ideally, integrating OSLog is the best. However, it's time-consuming and a lot of work needs to be done. This is good for now. Shota FUJI authored at Shota FUJI comitted at
  13. 790bc7fc macos: Fix crash on network error at server discovery Shota FUJI authored at Shota FUJI comitted at
  14. 8fdfb08d gtk-adwaita: Remove "develop build" style from window Even though there is some missing features (search and disconnect menu option,) it's usable for my day-to-day usage. Now all concurrency and memory bugs are fixed, this is the best timing to remove WIP label. Shota FUJI authored at Shota FUJI comitted at
  15. 5ed1b013 core: Give WS read and event handlers dedicated threads <https://codeberg.org/pocka/plac/issues/16> Parsing and handling incoming message in the same thread that reads WebSocket message from socket sometime drops WebSocket message, due to the thread being busy. This redesign solves that by separating reading and parsing/handling using dedicated threads. Although volume change operation now feels little bit sluggish, no more dropped response. Every operation is working correctly. Shota FUJI authored at Shota FUJI comitted at
  16. 12dfcdb9 core: Fix potential race condition Extremely rare, though (I saw only once.) Shota FUJI authored at Shota FUJI comitted at
  17. 03235177 core: Output request ID on control request send log "/control" endpoint suffers response loss as well as "/change_volume" endpoint. Request ID helps debugging this, because it's visible on data payload in Wireshark. Shota FUJI authored at Shota FUJI comitted at
  18. 05a6f716 gtk-adwaita: Volume controls While "it works," user experience is not great. For some reason, response for "/change_volume" got lost even though my machine sees a TCP packet. I also see this at "/control" endpoint too. However, "/seek" endpoint, which is called more frequently, does not encounter this. Most likely application problem given my experience on low-level programming, but it could be packet issue (Roon Server) or transport layer issue (websocket.zig or Linux?) I don't know, really. Shota FUJI authored at Shota FUJI comitted at
  19. 0a075ca6 core: Volume change functions Shota FUJI authored at Shota FUJI comitted at
  20. ba20af71 gtk-adwaita: Connect to server directly via IP address and port UDP multicast/broadcast is unreliable, especially in my environment where Roon server (or the machine hosting it) randomly stops responding to discovery query. Direct connection is really instant and I believe this would improve normal UX too. Shota FUJI authored at Shota FUJI comitted at
  21. 4b536649 core: Function to discovery server by IP address Roon Server or my server machine reject replying to UDP multicast/broadcast after several attempts. This functionality can be a good way to avoid UDP multicast and broadcast issues. Shota FUJI authored at Shota FUJI comitted at
  22. 0765fbd8 gtk-adwaita: Display zone outputs Shota FUJI authored at Shota FUJI comitted at
  23. d3f5d542 core: Expose zone outputs through C API Shota FUJI authored at Shota FUJI comitted at
  24. c69b6d06 core: Parse outputs in zone Shota FUJI authored at Shota FUJI comitted at
  25. 117a5ffa gtk-adwaita: Fix "Zone" dropdown button stretched vertically Shota FUJI authored at Shota FUJI comitted at
  26. e0f94d58 gtk-adwaita: Fix duplicated requests sent after reconnection <https://codeberg.org/pocka/plac/issues/13> Establishing a new connection registers a new callback to various signals without disconnecting stale ones, thus 1+(number of reconnections) requests have been made. Shota FUJI authored at Shota FUJI comitted at
  27. 9de7aad5 gtk-adwaita: Make playback toolbar layout tidier It has been unorgnaized and scattered due to unaligned elements and chaotic spacings. Shota FUJI authored at Shota FUJI comitted at
  28. 2fa47b61 gtk-adwaita: Fix playback toolbar size changes depends on track text If a track A contains non-Ascii text in title/subtitle and a track B does not, changing A to B or vice-versa causes height change for playback toolbar. This is because GTK.Label does not implement correct line-height handling, as it seems to simply calculate the height using the first font family and ignoring fallback fonts. Due to the lack of proper API on GTK (propbably also on Pango,) I opted to hard-code maximum size on each Gtk.Label. <https://codeberg.org/pocka/plac/issues/9> Shota FUJI authored at Shota FUJI comitted at
  29. b6093beb core: Fix random crash on opening a page having images This patch fixes random crash caused by race condition (use after free and unexplainable memory errors such as malloc in glib,) by properly guarding accesses to image download queue. Inside `while` loop reading the downloads queue, it read without lock and that caused reading of freed memory (`d == undefined`), thus operations like `d.data.arc.ref()` and `allocator.destroy(d)` to be invalid. Because the race condition occurs on downloads queue, opening browse page with massive items (200~) has been crashed the app frequently compared to small number of items (~50). Also, longer the image takes to load, more likely the crash to happens. So streaming service's browse page is more prone to crash than local library. With this change, I don't see random crash on Qobuz pages anymore. In addition, for some mysterious reason, images load faster than before. Definetely previous implementation did something wrong, as adding a lock does not make things faster but slower... <https://codeberg.org/pocka/plac/issues/15> Shota FUJI authored at Shota FUJI comitted at
  30. 14bf5e0a gtk-adwaita: Simplify settings binding for label parsing Shota FUJI authored at Shota FUJI comitted at
  31. 3e838e95 gtk-adwaita: Buttons to seek forward/backwards by 10 seconds Seekbar is not comfortable to use. Why 10 seconds, not 5 seconds? Because Adwaita has icons for 10 seconds but 5 seconds. Shota FUJI authored at Shota FUJI comitted at
  32. 412d59f0 gtk-adwaita: Fix cannot drag seekbar <https://codeberg.org/pocka/plac/issues/14> This is still not optimal, though. Ideally changes should debounce or throttle to reduce the number of request. But this works without crashing. Shota FUJI authored at Shota FUJI comitted at
  33. d64de6c8 gtk-adwaita: Loading and error state for Artwork widget Shota FUJI authored at Shota FUJI comitted at
  34. 9b107f4a gtk-adwaita: Workaround for Roon API returns "[[id|text]]" labels Shota FUJI authored at Shota FUJI comitted at
  35. e54e5874 core: Label parsing function Roon API returns "[[id|text]]" format strings for title and subtitles on some browse paths. For example, in my environment, "Explore > Qobuz > New Releases > Qobuz grand selection" returns items with subtitle in this format, like "[[969850|Wes Montgomery]]". I don't think we'll get a fix for this--Roon API is abandoned. Each client has to parse and throw IDs and brackets away. Shota FUJI authored at Shota FUJI comitted at
  36. 63589eaa gtk-adwaita: Remove useless function call Also Vala compiler has been emitting a warning that the variable is unused. Shota FUJI authored at Shota FUJI comitted at
  37. cf275126 gtk-adwaita: Fix space between rows react to clicks <https://codeberg.org/pocka/plac/issues/5> The bug was inside GTK4, and there seems no way to workaround from application developer side. I was not happy about aesthetic of the previous cards list, I simply changed the custom rows to regular one. Shota FUJI authored at Shota FUJI comitted at
  38. 26b2df71 core: Fix segfault on opening "Track" page with release builds The "node" inside while loop is a reference to the other thread's stack variable, and there is no mechanism to block a creator function from exiting. Since blocking a creator function could lead to unpleasing UX (images at beginnings load slowly compared to later images,) I simply changed the code to allocate nodes on heap and added RC. Shota FUJI authored at Shota FUJI comitted at
  39. 8a05c1ce Install code formatter for Nix Amount of Nix code is no longer little. Shota FUJI authored at Shota FUJI comitted at
  40. d82b40d0 gtk-adwaita: Configure Nix build/package Shota FUJI authored at Shota FUJI comitted at
  41. b943cd16 gtk-adwaita: About dialog Shota FUJI authored at Shota FUJI comitted at
  42. 5949d43c gtk-adwaita: Fix browse error locks browse UI into disabled state Shota FUJI authored at Shota FUJI comitted at
  43. 90a7baf9 gtk-adwaita: Don't render non-actionable item as actionable Shota FUJI authored at Shota FUJI comitted at
  44. d497c6aa gtk-adwaita: Don't scroll after selecting/closing action menu popover It's annoying. Shota FUJI authored at Shota FUJI comitted at
  45. 1683e5fd gtk-adwaita: Render action list as menu button It was hard-to-grasp albeit not usable. Shota FUJI authored at Shota FUJI comitted at
  46. 70c1f75e core: Cache downloaded images Navigating through library pages (e.g. albums, artists) fetches same images over and over. In order to reduce load to Roon Server, I added stupid simple caching in front of image downloader. This significantly reduces HTTP GET calls on my library, especially "Tracks" page. The caching does almost nothing on Qobuz pages, though. In my testing, Qobuz images takes more time to load and only playlists have lot of duplicated images. Because of those, the existing "reuse ongoing GET request" mechanism eliminates duplicated GETs thus almost all of requests are unique. I don't believe this can be improved—nobody but Qobuz (perhaps Roon too?) can control, optimize, and estimate data appearance pattern on Qobuz pages. This cache implementation does not look great, but it works well. Shota FUJI authored at Shota FUJI comitted at
  47. bcf2497d core: Download image using normal HTTP instead of WebSocket Downloading large number of images through WebSocket easily clogs connection and affects sending of other actions (e.g. playback control) and receiving of events. By using normal HTTP via separate connection, this no longer happens. This patch finally enables me to open "Explore > Library Tracks" page. Shota FUJI authored at Shota FUJI comitted at
  48. a6d963af core: Relax timeouts It was too short. Especially browse APIs frequently timed-out on Qobuz pages. Shota FUJI authored at Shota FUJI comitted at
  49. 9fc84020 core: Limit number of concurrent image downloads To prevent server from choked. Unfortunately, due to high duplication, "Library > Tracks" still timeouts and renders app unresponsive. Shota FUJI authored at Shota FUJI comitted at
  50. b269cbba gtk-adwaita: Browse category sidebar Shota FUJI authored at Shota FUJI comitted at
  51. 7f2d5aeb gtk-adwaita: Seek feature GTK4's slider/range widget is shitty, thus this feature works shitty as well. There are no "drag ended" equivalent signal and drag start emits JUMP scroll type value change signal. Also, setting `false` to `sensitive` resets focus so long jump using keyboard is impossible too. Debouncing or throttling would help a little bit, but won't solve the problem fundamentally. Seek change events sent by server would resets drag operation. Valadoc shows no result for "throttle/debounce" and GTK4 seems to have no function and widget for that. Implementing debounce/throttle function by hand, testing that, and adding additional delay to seek triggered by seek is not acceptable given those won't work when a track is playing. The only way to solve this is implementing custom widget, which means re-implementing slider UI from scratch or carefully patching and workarounding GtkRange's internal implementation. Both are time-consuming, exhausting, negatively effects maintainability, and stupid. GTK4's rendered widget is great. Its API and abstraction are dogshit. Shota FUJI authored at Shota FUJI comitted at
  52. 5c3de821 core: Seek function Shota FUJI authored at Shota FUJI comitted at
  53. 1be9ec56 core: Fix race condition on reconnect Shota FUJI authored at Shota FUJI comitted at
  54. c5b9431d gtk-adwaita: Automatic reconnection on server close *Not tested* Testing against Roon Server is really frustrating task. Shota FUJI authored at Shota FUJI comitted at
  55. 9ed2fe6d core: Reduce chance of timeout for request reuses Shota FUJI authored at Shota FUJI comitted at
  56. 1a88a96c core: Refactor to use constant defined in std Did not notice the constant at the time of writing the logic. Shota FUJI authored at Shota FUJI comitted at
  57. 71e09e36 core: Set timeout for requests Shota FUJI authored at Shota FUJI comitted at
  58. c491d8b6 core: Return result for control request This is required to implement timeout. Shota FUJI authored at Shota FUJI comitted at
  59. f5b7f026 gtk-adwaita: Display browse list subtitle Shota FUJI authored at Shota FUJI comitted at
  60. 8116f858 core: Do not send duplicated request for image downloads Previously there were multiple requests made to the same image_key and options pair. This is problematic on opening "Library > Tracks", because the page has a lot of same images. Shota FUJI authored at Shota FUJI comitted at
  61. 11f43c3c gtk-adwaita: Add a11y label to browse back button Shota FUJI authored at Shota FUJI comitted at
  62. 65f4d25e gtk-adwaita: Add a11y label for seekbar Shota FUJI authored at Shota FUJI comitted at
  63. 00ba47fb gtk-adwaita: Display current seek position as a tooltip Shota FUJI authored at Shota FUJI comitted at
  64. 94edd150 gtk-adwaita: Remove browse items' angle icon from AT It's just for presentation. To be honest, I have no idea what to label it. "Arrow indicating next navigation"? Shota FUJI authored at Shota FUJI comitted at
  65. 659b1c11 gtk-adwaita: Remove artwork from accessibility tree I have no control over the image. Announcing it as "artwork of <track>" does not bring new information. Shota FUJI authored at Shota FUJI comitted at
  66. dad9c096 core: Rename service modules Names are not best (they are CamelCase instead of snake_case) but one level less nesting is good enough for now. Shota FUJI authored at Shota FUJI comitted at
  67. e23a985c core: Upgrade libmoo (u64 request_id migration) libmoo previously used i64 for request_id. While Roon server accepts requests with i64 request_id, having negative number IDs looks weird. Also, the current implementation starts from 0 thus half of the space has been remaining unused. Using u64 for request_id just has pros. Shota FUJI authored at Shota FUJI comitted at
  68. ca23543a gtk-adwaita: Scroll to top on browser navigation Although not ideal, better than restoring to nonsensical position. Shota FUJI authored at Shota FUJI comitted at
  69. 714b10e5 gtk-adwaita: Display artwork on browse item Shota FUJI authored at Shota FUJI comitted at
  70. 13eb02e0 gtk-adwaita: Remove AppImage build Built AppImage won't launch. Shota FUJI authored at Shota FUJI comitted at
  71. 5f1a9e50 gtk-adwaita: build step for AppImage (broken) While the step produces `Plac.AppImage`, built file does not run with this error: ``` ./zig-out/Plac.AppImage: error while loading shared libraries: libharfbuzz.so.0: cannot open shared object file: No such file or directory ``` harfbuzz is installed but AppImage can't load the non-bundled library. I have no idea where is the problem: it could be Zig compiler, Nix, linuxdeploy, or my environment. AppImage docs is pretty shallow and scattered, recommended tools are questionable quality, but most importantly, the whole concept seems not to work well with Nix. Even if the underlying problem will be solved, this won't be in the repository. Given many errors and quirks I've seen at this point, I don't think it'll work in others' environments. Although it's not user friendly, running `nix develop && zig build run` is way better than CMake or Bazel or `configure` or whatever. I'm going to put this commit in trunk as build scripts and newly added files are useful for non-AppImage builds. Shota FUJI authored at Shota FUJI comitted at
  72. d49fc523 gtk-adwaita: Add app icon Required for generating an AppImage file. Shota FUJI authored at Shota FUJI comitted at
  73. 9cde9caf gtk-adwaita: Suppress deprecation warnings from Vala compiler See code comment for rationale. Shota FUJI authored at Shota FUJI comitted at
  74. b6090f98 gtk-adwaita: Remove unhelpful debug log These lines were added to debug a particular problem, which has been solved. As "what was changed" is unclear from log text, these are not useful and are simply noise. Shota FUJI authored at Shota FUJI comitted at
  75. 2eaaa39f gtk-adwaita: Display artwork on playback toolbar Shota FUJI authored at Shota FUJI comitted at
  76. 52fba235 core: Fix Image.GetOptions.make not retaning Shota FUJI authored at Shota FUJI comitted at
  77. 72c232bb core: Fix Image.GetOptions' constructor is missing in VAPI Shota FUJI authored at Shota FUJI comitted at
  78. 7ccb379d core: Fix vapi definition Shota FUJI authored at Shota FUJI comitted at
  79. c6c18e49 core: Add image_key to NowPlaying Shota FUJI authored at Shota FUJI comitted at
  80. 81995d12 core: Remove unnecessary internal slice fields Those were there for easy access and release. However, manually reconstructing a slice from a pointer (and a length) is not tedious or difficult. 8 bytes to 24 bytes reduction per objects. Shota FUJI authored at Shota FUJI comitted at
  81. 745ba05b core: Fix incorrect log message Shota FUJI authored at Shota FUJI comitted at
  82. fb7617ab gtk-adwaita: Prevent navigations during relavant request To avoid messing up Roon's server-side state management. Clients have to carefuly mutate server-side state, fuck. Shota FUJI authored at Shota FUJI comitted at
  83. c8a39931 gtk-adwaita: Disable playback control during request To prevent excess requests and such. Shota FUJI authored at Shota FUJI comitted at
  84. 8ac3a8fc core: Wait for control response Responses have been logged as unhandled message at warning level. Shota FUJI authored at Shota FUJI comitted at
  85. a621bc3a gtk-adwaita: Fix connection error banner triggers warnings Whenever connection error happens, GTK emits quite a few errors like: ``` Gtk-WARNING **: 10:28:43.818: Widget reports min height of 103 for width of 509, but min width of 184 for height of 46 ``` where each numbers slightly varies between log lines. Instead of addressing this stupid and cryptic warning, I choose to avoid the whole layout shenanigans by overlaying the banner. I feel how Flexbox is great nowadays. Shota FUJI authored at Shota FUJI comitted at
  86. 6bc46b51 core: Fix non-small WebSocket response cause panic websocket.zig has small max-size, and it was the culprit for GTK-Adwaita app crashing on opening "Library > Tracks". Shota FUJI authored at Shota FUJI comitted at
  87. f8c96337 cli: "image" command To quickly test Image API. Shota FUJI authored at Shota FUJI comitted at
  88. 8d5fab6e core: Image API Shota FUJI authored at Shota FUJI comitted at
  89. 627938ae cli: Display image_key property of an album This information is required for upcoming "image" command. Shota FUJI authored at Shota FUJI comitted at
  90. d4bcfe2e Update README Shota FUJI authored at Shota FUJI comitted at
  91. 22f48ee7 macos: Add README Shota FUJI authored at Shota FUJI comitted at
  92. cf03d5ac cli: Update README Shota FUJI authored at Shota FUJI comitted at
  93. 4da3008a core: Update README Content is obsolete. Also there are syntax errors in Zig sample code. Shota FUJI authored at Shota FUJI comitted at
  94. cbc8bdd0 gtk-adwaita: Update README Shota FUJI authored at Shota FUJI comitted at
  95. f29f08c8 gtk-adwaita: Add `run` step It's vastly simpler than manually invoking schema complication and specifying an output path of the step. Shota FUJI authored at Shota FUJI comitted at
  96. c873534e gtk-adwaita: Change browser background color Why did I set the whole browser pane to "view" instead of making "ListBox"'s "background"? I don't know. Shota FUJI authored at Shota FUJI comitted at
  97. 442a666d gtk-adwaita: Shrink browser title font size It standed out too much. The added margins are necessary for maintaining line-height when a back button is absent. Shota FUJI authored at Shota FUJI comitted at
  98. 99f09410 gtk-adwaita: Fix window can't be narrow like 320px. GTK by default displays texts without wrapping thus the loading message sets minimum window size to its length. Shota FUJI authored at Shota FUJI comitted at
  99. 041c8ae0 core: Fix reconnect keeping discarded connections Shota FUJI authored at Shota FUJI comitted at
  100. 836c2fc4 gtk-adwaita: Fix long texts widen window Shota FUJI authored at Shota FUJI comitted at
  101. 7612e6b0 gtk-adwaita: Browse view It's not complete: crashes on large items (e.g. Library > Tracks), everything is styled as list navigation, non "list" responses are ignored, etc. But it does the job. I have many things to do such as handling connection close by server and implementing application menu. Shota FUJI authored at Shota FUJI comitted at
  102. 288f3e05 cli: Format file with `zig fmt` Shota FUJI authored at Shota FUJI comitted at
  103. f46b6478 core: Fix "item_key" field is missing from Item Shota FUJI authored at Shota FUJI comitted at
  104. fdeba4e2 cli: Albums command To check memory errors for the browse module. The new `disconnect` method in core is, for now, used only by CLI. This command found a memory leak due connection module to forget retaining a `browse.Result` struct to be returned. This would not be obvious in GTK-Adwaita app, given how noisy Valgrind log because of GTK/GLib things leak stuffs even with supp files. Shota FUJI authored at Shota FUJI comitted at
  105. 49ef2b46 cli: Add -Dfreelog build option Shota FUJI authored at Shota FUJI comitted at
  106. 9a50b9be cli: Move connection establishment to dedicated file To use in other commands. Shota FUJI authored at Shota FUJI comitted at
  107. 5a0781da Use nixpkgs 25.05 channel It has zig 0.14. Shota FUJI authored at Shota FUJI comitted at
  108. cf742d30 core: Broadcast discovery query as well I don't know which Roon's software or my network settings is the problem though, discovery will be flaky randomly. Hope this improves. Shota FUJI authored at Shota FUJI comitted at
  109. 1a1e713b core: Conditionally output memory release log It's overwhelming for daily use. Shota FUJI authored at Shota FUJI comitted at
  110. ff2037b6 core: Browse API Shota FUJI authored at Shota FUJI comitted at
  111. ea54f0fb gtk-adwaita: Reset seekbar to start when playback is empty Previously, switching from playing zone to completely stopped (no queue item) zone kept seekbar position. It was confusing. Shota FUJI authored at Shota FUJI comitted at
  112. b2e3c347 core: Fix event parsing error on playback complete For some mysterious reason, Roon sends seek_change event without seek_position field, even though it sets `null` on other occasion. That has been causing MissingField error and that was the reason playback complete not updating playback toolbar on GTK adwaita app. Shota FUJI authored at Shota FUJI comitted at
  113. 424d58b0 core: Fix event parse error on prev-ing at last of queue For some reason, prev-ing at the last of a queue sends seek_change event with seek_position being null. That causes UnexpectedToken error on JSON parsing. Shota FUJI authored at Shota FUJI comitted at
  114. 45360213 core: Upgrade libmoo To use JSON stringify options. Shota FUJI authored at Shota FUJI comitted at
  115. 9eb4f42c gtk-adwaita: Show server name in window title Shota FUJI authored at Shota FUJI comitted at
  116. 40089fa6 gtk-adwaita: Proper style for playback UI Shota FUJI authored at Shota FUJI comitted at
  117. aae8758c gtk-adwaita: Seek bar Shota FUJI authored at Shota FUJI comitted at
  118. f814958a core: Seek change event Shota FUJI authored at Shota FUJI comitted at
  119. 915553e7 core/gtk-adwaita: Now playing info Shota FUJI authored at Shota FUJI comitted at
  120. cfcffb49 gtk-adwaita: Skip forward and backward buttons Shota FUJI authored at Shota FUJI comitted at
  121. a089a9dd gtk-adwaita: Rename Plac/Discovery.vala to Plac.vala The file contains non-Discovery code. Shota FUJI authored at Shota FUJI comitted at
  122. 848c1b69 gtk-adwaita: Play and pause control Shota FUJI authored at Shota FUJI comitted at
  123. 3ac492f2 core: Playback control API Shota FUJI authored at Shota FUJI comitted at
  124. 87e78be8 core: Parse allowed actions for a zone Required for playback controls. Shota FUJI authored at Shota FUJI comitted at
  125. d6154cfd core: Fix GLib error log terminates application GLib's error level log terminates application, even though the function is logging one and nothing says error is fatal to application. This bullshit design is the root cause of app crashes when server closed a connection. Shota FUJI authored at Shota FUJI comitted at
  126. 588336be gtk-adwaita: Display connection error Shota FUJI authored at Shota FUJI comitted at
  127. e0f587b9 macos: Minimal readonly toolbar (zone display) Shota FUJI authored at Shota FUJI comitted at
  128. 325ef897 macos: Init schema Why have the project been working for now without schema? idk. Shota FUJI authored at Shota FUJI comitted at
  129. 2040425f macos: Fix missing argument (compile error) Shota FUJI authored at Shota FUJI comitted at
  130. cd03a5ae gtk-adwaita: Save and restore connection Shota FUJI authored at Shota FUJI comitted at
  131. fa78ce00 gtk-adwaita: GSettings for connection state Shota FUJI authored at Shota FUJI comitted at
  132. d587253c cli: Playback command For testing token restoration. Shota FUJI authored at Shota FUJI comitted at
  133. 644556c3 core: Use saved token Shota FUJI authored at Shota FUJI comitted at
  134. 7120e027 core: Fix connection struct not released without manual ref Shota FUJI authored at Shota FUJI comitted at
  135. d530b378 cli: Connect command This patch also fixes find API not working on search hit. Shota FUJI authored at Shota FUJI comitted at
  136. 8edfd166 core: Server find API Shota FUJI authored at Shota FUJI comitted at
  137. 7c6f0d40 macos: UI for server discovery Shota FUJI authored at Shota FUJI comitted at
  138. f0f5f054 cli: Remove memcheck option Most of the time I run cli, it's for checking memory leaks. There is no usecase for disabling memcheck option. Shota FUJI authored at Shota FUJI comitted at
  139. 58c2a848 cli: Switch to new core I once considered removing "cli" together, but it's very useful at debugging memory leaks and such. Shota FUJI authored at Shota FUJI comitted at
  140. 047caaf8 core: Switch to Atomic Reference Counting I don't know how to trigger access error on non-atomic variant though. Shota FUJI authored at Shota FUJI comitted at
  141. c0364945 core: Workaround for Debug build crash on macOS Shota FUJI authored at Shota FUJI comitted at
  142. 3a4c2e2a macos: Use new core Shota FUJI authored at Shota FUJI comitted at
  143. 63e467c0 gtk-adwaita/core: Extract core logic to dedicated package I found out this logic for Gtk-Adwaita can be used naturally in Swift. Shota FUJI authored at Shota FUJI comitted at
  144. 357690b0 Rename "core" to "old_core" I'd like to rewrite it from scratch but existing usage prevents that. Shota FUJI authored at Shota FUJI comitted at
  145. f8d353fc gtk-adwaita: per app core instead of shared core Writing a library that is comfortable to use both in Vala and in Swift is really challenging. That makes library pretty C-ish, I mean barebone manual memory management which is hard to use, design and implement. By having dedicated Zig modules and extracting shared logic as a Zig module instead of C library, development speed and application quality will be improved thanks to more ergnomic API and natural memory management (reference counting). This commit does not include that "shared logic" part, because I have no idea how macos/ part will go on. Although the number of allocation massively increased due to heavy copy, chance of memory leak or invalid writes (double-free, use-after-free) is significantly lower compared to my previous shitty implementation. Shota FUJI authored at Shota FUJI comitted at
  146. 6d1b49ca Migrate from devbox to Nix Flake Turns out, versioned package manager powered by Nix, won't work. Many libraries, especially runtime dependencies, suffers from duplicated packages and application crashes with cryptic error messages. Shota FUJI authored at Shota FUJI comitted at
  147. 422c9306 gtk-adwaita: Style zone list like menu When navigating using keyboard, closing popover does not reset selection state thus UI goes incorrect state where inactive row can be displayed as active. However, I'm not going to spend times on details: functionality first. Shota FUJI authored at Shota FUJI comitted at
  148. 3b7f83e8 gtk-adwaita: Zone selection Now user can switch zone to show in UI. Shota FUJI authored at Shota FUJI comitted at
  149. 2fa4ec35 cli: Ignore Valgrind core dump Shota FUJI authored at Shota FUJI comitted at
  150. 2bbd18f1 core: Subscribe to zone updates Shota FUJI authored at Shota FUJI comitted at
  151. 1e9c2f8b core: Cancel pending response handler on deinit Shota FUJI authored at Shota FUJI comitted at
  152. 4c605385 gtk-adwaita: Fix closing on server selector doesn't exit application Shota FUJI authored at Shota FUJI comitted at
  153. 25cd076d core: Use thread pool so every threads will be closed Unterminated threads were noise on Valgrind. Shota FUJI authored at Shota FUJI comitted at
  154. a6de2c9e core: Fix size of struct containing `usize` being incorrect Shota FUJI authored at Shota FUJI comitted at
  155. 36158e3d gtk-adwaita: List zones and show playback state of the first one UI is shitty but it at least demonstrates zone fetching functionality. Shota FUJI authored at Shota FUJI comitted at
  156. 31f27d67 gtk-adwaita: Split widgets into separate files Shota FUJI authored at Shota FUJI comitted at
  157. 8cc196cb gtk-adwaita: Automatic lookup for resources and Vala source Shota FUJI authored at Shota FUJI comitted at
  158. b9dfb81f gtk-adwaita: Split connecting state to separate UI file Too much nesting. Shota FUJI authored at Shota FUJI comitted at
  159. 63ba1ec7 gtk-adwaita: Properly style connecting UI Shota FUJI authored at Shota FUJI comitted at
  160. e9531b48 core/gtk-adwaita: Export mutex API The initial plan was to complete every actions inside callbacks. However, most UI libraries/frameworks requires main thread for accessing UI. That means, state could be changed during the UI operation because it's outside the callback's mutex locking. Shota FUJI authored at Shota FUJI comitted at
  161. 9ed3f8f9 gtk-adwaita: Access GTK only from main thread App was flaky due to off-thread accesses. Shota FUJI authored at Shota FUJI comitted at
  162. 1aa6eb97 core: Disarm function should take context/user data too Since functions are static and what makes "function for this context" is a context pointer, disarm functions too have to take that. Shota FUJI authored at Shota FUJI comitted at
  163. 588603fc core: Remove legacy manual API Shota FUJI authored at Shota FUJI comitted at
  164. 4b14946c Do not use swift-format@5.8 I thought it works okay even for Swift 6 source code given Swift 6 announcement post and various posts do not list syntax changes. They seem to be "docs does not matter, we have migration tool!" people. Somehow swift-format@5.8 rejects valid function call (in my case, it was struct initializer) and if I commented the relavant section, it messed code so badly that I had to "fix" every unnecessary stupid newlines. Until nixpkgs or Swift team fixes build pipeline, I have to manually invoke the latest swift-format via XCode. fuck. Shota FUJI authored at Shota FUJI comitted at
  165. 496f08e9 macos: Migrate to new C API Shota FUJI authored at Shota FUJI comitted at
  166. 8a172f02 gtk-adwaita: Save and restore connection It's extremely flaky due to thread unsafety... I have to organize callbacks sure. Shota FUJI authored at Shota FUJI comitted at
  167. 9435612b core: Save connection state to a file Previously I thought each apps having platform specific save logic would be better than implementing it in the core. However, Vala has no simple way to do that (had to import various GLib things). Apparently every platform I plan to implement uses file system for state files, thus implementing in the core is safe as long as it takes full file path. Shota FUJI authored at Shota FUJI comitted at
  168. 3f169255 core: Avoid implicit pass-by-reference conversion Shota FUJI authored at Shota FUJI comitted at
  169. 5dc2caa9 core: Comment on why `scan_result` is not deinit-ed I thought it's confusing during refactoring. Shota FUJI authored at Shota FUJI comitted at
  170. 6755b30b core: Adhere init/deinit to guideline This makes "who manages this memory" more obvious. Shota FUJI authored at Shota FUJI comitted at
  171. 8b399348 core: Docs for code style This is solo development project but I'm already confused due to inconsistency. As there is no general Zig guidelines, I had to make a one for this project. For brevity, this commit does not touch Zig source code. This merely creates a guideline. Shota FUJI authored at Shota FUJI comitted at
  172. 96637ddb gtk-adwaita: Migrate to the new Core API This commit includes changes to Core: debug logging and fixing array of structure to array of pointer for structure. Although client code got simpler, I'm not sure accessing GTK from callback function is okay. For now, every callbacks are invoked from spawned thread and this means accessing GTK from non-UI thread. Additional async-ing in Vala side might be necessary? Shota FUJI authored at Shota FUJI comitted at
  173. 43a74204 core: Migrate to callback design Forcing callers to take care of threads turned out a bad idea. That requires core to be extremely simple, durable, and thread-safe. By making majority of core's functionality threaded, clients do not have to take a look inside to see whether a field is thread-safe or not. Shota FUJI authored at Shota FUJI comitted at
  174. e0277f46 core: Fix memory leaks Shota FUJI authored at Shota FUJI comitted at
  175. b2b447f1 cli: Fix memory leak Shota FUJI authored at Shota FUJI comitted at
  176. 00258b0e core: Remove obsolete TODO comment Shota FUJI authored at Shota FUJI comitted at
  177. 5c7effd2 core: Release unhandled response bytes on deinit Shota FUJI authored at Shota FUJI comitted at
  178. f3fa46a4 core: Return result code and token from connect method Shota FUJI authored at Shota FUJI comitted at
  179. ab47cb29 cli: Escape server name and version in TSV output Shota FUJI authored at Shota FUJI comitted at
  180. 49d86a77 cli: Create exit code for stdout write error Shota FUJI authored at Shota FUJI comitted at
  181. 6ac67e0a cli: Create exit code for OOM Shota FUJI authored at Shota FUJI comitted at
  182. ebb7ce2e gtk-adwaita: Fix runtime library error on macOS libadwaita depends on gtk4 but devbox cannot resolve to same package as the root one, so there are duplicated "gtk4" package therefore symbol duplication error happens. I have no idea why this is not a problem on Linux, though. Shota FUJI authored at Shota FUJI comitted at
  183. ed3b9ab8 gtk-adwaita: Init core app I have no idea what to do next. Flux-like state-action API? Simple struct with state properties and callback functions like GObject? Completely lost. Shota FUJI authored at Shota FUJI comitted at
  184. c7269fdd core: Setup debug logs Shota FUJI authored at Shota FUJI comitted at
  185. 31fe7e9b core: Use proper logging Shota FUJI authored at Shota FUJI comitted at
  186. 8d7910f5 cli: Use proper logging Shota FUJI authored at Shota FUJI comitted at
  187. 248e9669 core/cli: Get list of available zones Shota FUJI authored at Shota FUJI comitted at
  188. 4f914150 core/cli: Register extension to Roon Code is messy. Logs should be proper logs not debug one. Few places leaks memory. WebSocket read timeout should be configurable. CLI should also store IP address and TCP port. Error handling is nonexistent. However, it works (TM). And if I optimize or tidy I/F up at this point, there is high chance of the resulted code would be difficult to use. Tidying I/F by seeing only one implementation (in this case, CLI) brings other client hard time integrating. This project's main focus is native GUI clients, not CLI. Thus, I should refactor/optimize at the time of writing GTK or SwiftUI code. Let it evolve from worse state. Shota FUJI authored at Shota FUJI comitted at
  189. 190d510d core: Move server discovery code to "server/" dir I could not put playback related functionality to "lib.h" safely. Shota FUJI authored at Shota FUJI comitted at
  190. f5785163 gtk-adwaita: Loading state for server discovery window Shota FUJI authored at Shota FUJI comitted at
  191. 9bebfb66 gtk-adwaita: Loading screen for server discovery Shota FUJI authored at Shota FUJI comitted at
  192. e97495e7 gtk-adwaita: Generic error dialog class To eliminate the duplication. Shota FUJI authored at Shota FUJI comitted at
  193. 0c6835fc gtk-adwaita: Improve writing and styles of error dialogs Shota FUJI authored at Shota FUJI comitted at
  194. dc5a9a93 gtk-adwaita: Server discovery error handling Loading is still work-in-progress, but error handling is okay. There must be better way to disconnect a signal (error_detail_hid) though. Shota FUJI authored at Shota FUJI comitted at
  195. 96c37943 gtk-adwaita: Use Gnome UI components Shota FUJI authored at Shota FUJI comitted at
  196. 9423b7c4 gtk-adwaita: Rename from "gtk" I'm not going to do "pure GTK", as the primary reason to use GTK is creating native looking GUI. If I freely build styles using GTK components, it would then look alien due to web-by styles. Shota FUJI authored at Shota FUJI comitted at
  197. fdd1d11a core: Find Roon Server by unique ID Except the very initial setup, clients have previously connected Server's unique ID. There is virtually no reason to perform enumerate servers on a network in that case. Shota FUJI authored at Shota FUJI comitted at
  198. 0255a14a core: Fix memory leaks Thanks, valgrind. You're awesome. Shota FUJI authored at Shota FUJI comitted at
  199. 29e4e7f8 cli: Fix memory leak Shota FUJI authored at Shota FUJI comitted at
  200. 762ad37d cli: Fix failing to build Shota FUJI authored at Shota FUJI comitted at
  201. 488e6c8c core/cli: Drop Zig API The primary purpose of cli is to test C API. However, Zig's ideal API design and one of C API is drastically different (esp. allocation), and that makes designing C API difficult. This simplifies the process and hopefully brings better C API with less memory mis-managements. Shota FUJI authored at Shota FUJI comitted at
  202. 38f47e6c core: Fix memory access violation on macos app I forgot C enum is platform int. No idea why this wasn't a problem on Vala, though. Shota FUJI authored at Shota FUJI comitted at
  203. 88a3effa macos: Display Roon Servers on network Shota FUJI authored at Shota FUJI comitted at
  204. 627429da core/macos: Import core from macos https://mitchellh.com/writing/zig-and-swiftui This blog post hugely helped me writing build scripts... I could not do this without that blog post. Shota FUJI authored at Shota FUJI comitted at
  205. e92280ed Remove vala-language-server from tool installation It requires Meson (no way) or Clang's `compile_commands.json` to understand dependencies. While the latter looks simple, I'm not willing to maintain duplicated compile command. If bug or unconvenience or frustration or whatever reaches certain threshold, I'll reconsider re-introducing the LS. Shota FUJI authored at Shota FUJI comitted at
  206. 319cb3a3 macos: macOS app development setup Shota FUJI authored at Shota FUJI comitted at
  207. 7a323e0e gtk: Display scanned Roon Servers No empty state, no error handling, though. Shota FUJI authored at Shota FUJI comitted at
  208. ff30d4c7 core: Fix build fails on macOS Interestingly, Zig smartly assigns `u31` as the type of `usec`. ```zig @compileLog(@typeName(@TypeOf(usec))); ``` yields, ``` @as(*const [3:0]u8, "u31") ``` Shota FUJI authored at Shota FUJI comitted at
  209. 647bb5b2 Don't install Valgrind on macOS It's marked as broken on darwin, despite search.nixos.org lists darwin platforms at "Platforms" section. Shota FUJI authored at Shota FUJI comitted at
  210. 9b785fff core/gtk: C API and use it from Vala Shota FUJI authored at Shota FUJI comitted at
  211. a079c8cd core: Simpler memory management for "Server" Although this increases memory allocation, API is simple and easier to build C API. Shota FUJI authored at Shota FUJI comitted at
  212. eefc813d gtk: Build GTK app using Zig build system It's convenient, consistent, and reliable. Goodbye, system CC's bullshit warnings. Shota FUJI authored at Shota FUJI comitted at
  213. 62d9a8b8 cli: JSONL output for "server ls" ``` ./zig-out/bin/plac server ls -f jsonl | jq ``` Shota FUJI authored at Shota FUJI comitted at
  214. 9fc8db70 core: Set HTTP port to ip_addr field Having separate HTTP port and keeping UDP source port is wasteful and not user friendly. Shota FUJI authored at Shota FUJI comitted at
  215. 9498d876 cli: Improve memory debuggability Now DebugAllocator can detect memory leaks. Shota FUJI authored at Shota FUJI comitted at
  216. 995d035e core: Fix server list not deduped due to double free ``` valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --num-callers=15 -s ./zig-out/bin/plac server ls -c 10 ``` When a same Roon Server responds more than one time, servers hashmap gets corrupted entry due to having a free-d key. Shota FUJI authored at Shota FUJI comitted at
  217. ce738568 cli: Replace "calloc" build option with "memcheck" option For more enriched debugging. Valgrind is super useful but Zig's DebugAllocator displays more friendly message. It does not catch all errors so Valgrind is still necessary. Shota FUJI authored at Shota FUJI comitted at
  218. eac279a7 cli: Fix main not executing defer statements Shota FUJI authored at Shota FUJI comitted at
  219. 482b779c Add valgrind debugging Shota FUJI authored at Shota FUJI comitted at
  220. eec7b07a core/cli: Roon Server discovery It works (TM) quality though. Shota FUJI authored at Shota FUJI comitted at
  221. b4642ced cli: register "server list" command Not doing anything useful for now, though. Shota FUJI authored at Shota FUJI comitted at
  222. 96b2faf4 cli: Basic CLI setup Shota FUJI authored at Shota FUJI comitted at
  223. 88ae701c cli: Zig project setup Shota FUJI authored at Shota FUJI comitted at
  224. 621870cd gtk: Fix build error on macOS ``` error: Failed to execute child process “pkg-config” (No such file or directory) ``` Shota FUJI authored at Shota FUJI comitted at
  225. 5260c3be gtk: GTK4 application project setup I still have no idea how "libadwaita" alone supplies required dependencies such as pango and glib. Without that, even adding those to "packages" section, ld complains files are missing. Ghostty has "libadwaita" and "gtk4" as dependencies for GTK4 so I simply did the same. Shota FUJI authored at Shota FUJI comitted at
  226. f11a7f77 Manage tools using Devbox rather than mise-en-place/asdf Vala, a programming language often(?) used in GTK world, is missing from mise/asdf registries. I've been feeling itches while using mise/asdf due to lack of packages. For example, REUSE tool, which I use for most of my recent projects, does not exist in their registries. I choose Devbox among the three options: * devenv * Nix Flake (without helper tools) * Devbox ## devenv This is the first tool I tried. Their website looks good, features sounds good, and sample Nix file looks okay. Their getting started guide starts with "devenv init", which creates not only their config file but touches other toolings' files (`.gitignore` and `.envrc`). "init" command without manual setup step, especially touching others' files is big sign of shitty tooling design, but I continued hoping other parts would be "okay". Unfortunately they weren't. CLI "search" command emits hundres of warnings, and outputs table does not check terminal width so it badly wraps and border characters gets in a way that the output is nearly unreadable. When I ran its shell command, it paused the execution with a warning message about binary cache. So devenv by default uses creator's own paid SaaS? I don't think just using devenv requires paid subscription, but unclear writing and CLI tries to push Cachix service into users' Nix config is no-no for me. The tool seems to be a thin wrapper around Nix: it inherits some of upstream's bad designs (e.g. absolutely worst error trace, "nix develop" invokes "bash" regardless of the current shell). Their website advertise "Version support." but very few selected packages have that. Everything else relies on Nix's "use latest or die" versioning schema. Considering devenv's "Language support" is just import helpers for nixpkgs, this "Version support." feels like a false advertising. Half-baked YAML/Nix architecture prevents users from using overlays or other flakes with "follows" input to reduce duplications. And using Flake requires running Flake command ("nix develop --no-pure-eval") instead of their CLI, which completely dismissed the value of their tool for me. Also reading their docs are uncomfortable given the tool is not good quality one: > Many experienced Nix users prefer to use Nix flakes, although devenv > is considered a superior interface since it's way simpler, but lacks > integration with existing tooling. Superior, huh? There are still features not present in bare Nix/Flake, but I find those scripts/tasks/tests not useful. If every developer has access to same toolchains, why not simply write script? (JS or Python or Go or whatever) Overall, I see no benefits over bare Nix/Flake or mise/asdf. ## Nix Flake Nix the language is ugly and readability is mediocre (I maintain my machines using Home Manager and still hard time *parsing* program.) It's not good at handling toolchain versions and I don't believe people not using Nix regularly can understand/write even *okay* quality code. Combined with its worst of the worst debuggability, I mean error trace, this is not something I'd like to maintain alongside application development. But most importantly, they still runs "bash" on "nix develop" even a user uses zsh or fish. Hard pass. ## Devbox Actually this was not in my radar initially, but found during figuring best way to write Flake for monorepo. It's not a kind of software I like: docs are next to a cloud offering, docs site hosted on Vercel, corporate site calling nonsense-text- generators-having-high-chance-of-makes-sense-response "AI" without defining intelligence or artifical one, allowing JSONC for ".json" file extension (fuck you M$ for starting this fucking tradition) and not supporting ".jsonc" file extension. But the tool itself is good actually. * Config file is JSON rather than YAML. * Config schema is concise and straightforward. * CLI works great. No wrapping tables. * CLI is fast. * Structure of their docs website is *great*. I should steal from that. * Supports versions, really. It's hard to describe... UX for Devbox is similar to or better than mise-en-place. Simplicity? No bullshit API design? I don't know. I find this tool to be simpler to use and easier to understand compared to other tools, even including non-Nix ones such as asdf, nvm, and mise. I may encounter problems rooted to Devbox in a future. I may get frustrated due to mistyping "debvoc" or something. But for now, I believe Devbox is the best suited for this project (and my other projects too.) Shota FUJI authored at Shota FUJI comitted at
  227. e7e581ad core: Zig project setup Shota FUJI authored at Shota FUJI comitted at
  228. e2a91fa9 README.md and Markdown authoring setup Shota FUJI authored at Shota FUJI comitted at
  229. 4b704338 Create a license file I don't care someone using this for profit or whatever. This project started because the status quo is terrible. Shota FUJI authored at Shota FUJI comitted at