Druid v0.7.0 Release Notes

Release Date: 2021-01-01 // almost 2 years ago
  • Highlights

    • ๐Ÿ‘ Text improvements: TextLayout type ([#1182]) and rich text support ([#1245])
    • The Formatter trait provides more flexible handling of conversions between values and their textual representations. ([#1377])

    โž• Added

    • ๐Ÿ Windows: Added Screen module to get information about monitors and the screen. ([#1037] by [@rhzk])
    • โž• Added documentation to resizable() and show_titlebar() in WindowDesc. ([#1037] by [@rhzk])
    • ๐Ÿ Windows: Added internal functions to handle Re-entrancy. ([#1037] by [@rhzk])
    • ๐Ÿ Windows: WindowDesc: Create window with disabled titlebar, maximized or minimized state, and with position. ([#1037] by [@rhzk])
    • ๐Ÿ Windows: WindowHandle: Change window state. Toggle titlebar. Change size and position of window. ([#1037], [#1324] by [@rhzk])
    • ๐Ÿ Windows: WindowHandle: Added handle_titlebar(), Allowing a custom titlebar to behave like the OS one. ([#1037] by [@rhzk])
    • OPEN_PANEL_CANCELLED and SAVE_PANEL_CANCELLED commands. ([#1061] by @cmyr)
    • 0๏ธโƒฃ Export Image and ImageData by default. ([#1011] by [@covercash2])
    • Re-export druid_shell::Scalable under druid namespace. ([#1075] by [@ForLoveOfCats])
    • ๐Ÿ‘ TextBox now supports ctrl and shift hotkeys. ([#1076] by [@vkahl])
    • ScrollComponent for ease of adding consistent, customized, scrolling behavior to a widget. ([#1107] by [@ForLoveOfCats])
    • Selection text color to textbox. ([#1093] by [@sysint64])
    • BoxConstraints::UNBOUNDED constant. ([#1126] by [@danieldulaney])
    • Close requests from the shell can now be intercepted ([#1118] by [@jneem], [#1204] by [@psychon], [#1238] by [@tay64])
    • ๐Ÿ‘ The Lens derive now supports an ignore attribute. ([#1133] by [@jneem])
    • โšก๏ธ request_update in EventCtx. ([#1128] by [@raphlinus])
    • ExtEventSinks can now be obtained from widget methods. ([#1152] by [@jneem])
    • 'Scope' widget to allow encapsulation of reactive state. ([#1151] by [@rjwittams])
    • Ref lens that applies AsRef and thus allow indexing arrays. ([#1171] by [@finnerale])
    • Command::to and Command::target to set and get a commands target. ([#1185] by [@finnerale])
    • Menu commands can now choose a custom target. ([#1185] by [@finnerale])
    • ๐Ÿšš Movement::StartOfDocument, Movement::EndOfDocument. ([#1092] by [@sysint64])
    • TextLayout type simplifies drawing text ([#1182] by [@cmyr])
    • โž• Added support for custom mouse cursors ([#1183] by [@jneem])
    • Implementation of Data trait for i128 and u128 primitive data types. ([#1214] by [@koutoftimer])
    • ๐Ÿ”ง LineBreaking enum allows configuration of label line-breaking ([#1195] by [@cmyr])
    • ๐Ÿ‘ TextAlignment support in TextLayout and Label ([#1210] by [@cmyr])
    • ๐Ÿ”„ UpdateCtx gets env_changed and env_key_changed methods ([#1207] by [@cmyr])
    • Button::from_label to construct a Button with a provided Label. ([#1226] by [@ForLoveOfCats])
    • Lens: Added Unit lens for type erased / display only widgets that do not need data. ([#1232] by [@rjwittams])
    • WindowLevel to control system window Z order, with Mac and GTK implementations ([#1231] by [@rjwittams])
    • WIDGET_PADDING items added to theme and Flex::with_default_spacer/Flex::add_default_spacer ([#1220] by [@cmyr])
    • ๐Ÿ”ง CONFIGURE_WINDOW command to allow reconfiguration of an existing window. ([#1235] by [@rjwittams])
    • โž• Added a ClipBox widget for building scrollable widgets ([#1248] by [@jneem])
    • RawLabel widget displays text Data. ([#1252] by [@cmyr])
    • 'Tabs' widget allowing static and dynamic tabbed layouts. ([#1160] by [@rjwittams])
    • RichText and Attribute types for creating rich text ([#1255] by [@cmyr])
    • request_timer can now be called from LayoutCtx ([#1278] by [@Majora320])
    • ๐Ÿšš TextBox supports vertical movement ([#1280] by [@cmyr])
    • Widgets can specify a baseline, flex rows can align baselines ([#1295] by [@cmyr])
    • TextBox::with_text_color and TextBox::set_text_color ([#1320] by [@cmyr])
    • โšก๏ธ Checkbox::set_text to update the label. ([#1346] by [@finnerale])
    • Event::should_propagate_to_hidden and Lifecycle::should_propagate_to_hidden to determine whether an event should be sent to hidden widgets (e.g. in Tabs or Either). ([#1351] by [@andrewhickman])
    • โšก๏ธ set_cursor can be called in the update method. ([#1361] by [@jneem])
    • WidgetPod::is_initialized to check if a widget has received WidgetAdded. ([#1259] by [@finnerale])
    • TextBox::with_text_alignment and TextBox::set_text_alignment ([#1371] by [@cmyr])
    • โž• Add default minimum size to WindowConfig. ([#1438] by [@colinfruit])
    • ๐Ÿ”ง Open and save dialogs send configurable commands. ([#1463] by [@jneem])
    • Windows: Dialogs now respect the parameter passed to force_starting_directory() ([#1452] by [@MaximilianKoestler])
    • Value formatting with the Formatter trait ([#1377] by [@cmyr])

    ๐Ÿ”„ Changed

    • ๐Ÿ Windows: Reduced flashing when windows are created on high-dpi displays ([#1272] by [@rhzk])
    • ๐Ÿ Windows: Improved DPI handling. Druid should now redraw correctly when dpi changes. ([#1037] by [@rhzk])
    • ๐Ÿ windows: Window created with OS default size if not set. ([#1037] by [@rhzk])
    • Scale::from_scale to Scale::new, and Scale methods scale_x / scale_y to x / y. ([#1042] by [@xStrom])
    • Major rework of keyboard event handling. ([#1049] by [@raphlinus])
    • Container::rounded takes KeyOrValue<f64> instead of f64. ([#1054] by [@binomial0])
    • request_anim_frame no longer invalidates the entire window. ([#1057] by [@jneem])
    • ๐Ÿ‘‰ Use new Piet text api ([#1143] by [@cmyr])
    • Env::try_get (and related methods) return a Result instead of an Option. ([#1172] by [@cmyr])
    • ๐Ÿšš lens! macro to use move semantics for the index. ([#1171] by [@finnerale])
    • Env stores Arc<str> instead of String ([#1173] by [@cmyr])
    • Replaced uses of Option<Target> with the new Target::Auto. ([#1185] by [@finnerale])
    • ๐Ÿšš Moved Target parameter from submit_command to Command::new and Command::to. ([#1185] by [@finnerale])
    • ๐Ÿšš Movement::RightOfLine to Movement::NextLineBreak, and Movement::LeftOfLine to Movement::PrecedingLineBreak. ([#1092] by [@sysint64])
    • ๐Ÿšš AnimFrame was moved from lifecycle to event ([#1155] by [@jneem])
    • ๐Ÿšš Renamed ImageData to ImageBuf and moved it to druid_shell ([#1183] by [@jneem])
    • Contexts' text() methods return &mut PietText instead of cloning ([#1205] by [@cmyr])
    • ๐Ÿ Window construction: WindowDesc decomposed to PendingWindow and WindowConfig to allow for sub-windows and reconfiguration. ([#1235] by [@rjwittams])
    • LocalizedString and LabelText use ArcStr instead of String ([#1245] by [@cmyr])
    • ๐Ÿšš LensWrap widget moved into widget module ([#1251] by [@cmyr])
    • Delegate::command now returns Handled, not bool ([#1298] by [@jneem])
    • ๐ŸŽ TextBox selects all contents when tabbed to on macOS ([#1283] by [@cmyr])
    • 0๏ธโƒฃ All Image formats are now optional, reducing compile time and binary size by default ([#1340] by [@JAicewizard])
    • The Cursor API has changed to a stateful one ([#1433] by [@jneem])
    • Part of the SAVE_FILE command is now SAVE_FILE_AS ([#1463] by [@jneem])

    ๐Ÿ—„ Deprecated

    • ๐Ÿ“œ Parse widget (replaced with Formatter trait) ([#1377] by [@cmyr])

    โœ‚ Removed

    • Scale::from_dpi, Scale::dpi_x, and Scale::dpi_y. ([#1042] by [@xStrom])
    • Scale::to_px and Scale::to_dp. ([#1075] by [@ForLoveOfCats])

    ๐Ÿ›  Fixed

    • ClipBox should forward events if any child is active, not just the immediate child. ([#1448] by [@derekdreery])
    • ๐ŸŽ macOS: Timers not firing during modal loop. ([#1028] by [@xStrom])
    • GTK: Directory selection now properly ignores file filters. ([#957] by [@xStrom])
    • GTK: Don't crash when receiving an external command while a file dialog is visible. ([#1043] by [@jneem])
    • Data derive now works when type param bounds are defined. ([#1058] by [@chris-zen])
    • โšก๏ธ Ensure that update is called after all commands. ([#1062] by [@jneem])
    • ๐Ÿ‘ X11: Support idle callbacks. ([#1072] by [@jneem])
    • GTK: Don't interrupt KeyEvent.repeat when releasing another key. ([#1081] by [@raphlinus])
    • Floor the origin for the Align widget to avoid blurry borders. ([#1091] by [@sysint64])
    • X11: Set some more common window properties. ([#1097] by [@psychon])
    • ๐Ÿ‘ X11: Support timers. ([#1096] by [@psychon])
    • โšก๏ธ EnvScope now also updates the Env during Widget::lifecycle. ([#1100] by [@finnerale])
    • WidgetExt::debug_widget_id and debug_paint_layout now also apply to the widget they are called on. ([#1100] by [@finnerale])
    • ๐Ÿ X11: Fix X11 errors caused by destroyed windows. ([#1103] by [@jneem])
    • โšก๏ธ ViewSwitcher now skips the update after switching widgets. ([#1113] by [@finnerale])
    • ๐Ÿ‘ฏ Key and KeyOrValue derive Clone ([#1119] by [@rjwittams])
    • ๐Ÿ‘ Allow submit_command from the layout method in Widgets ([#1119] by [@rjwittams])
    • ๐Ÿ‘ Allow derivation of lenses for generic types ([#1120]) by [@rjwittams])
    • Switch widget: Toggle animation being window refresh rate dependent ([#1145] by [@ForLoveOfCats])
    • ๐Ÿ Multi-click on Windows, partial fix for #859 ([#1157] by [@raphlinus])
    • ๐Ÿ Windows: fix crash on resize from incompatible resources ([#1191 by [@raphlinus]])
    • ๐Ÿ— GTK: Related dependencies are now optional, facilitating a pure X11 build. ([#1241] by [@finnerale])
    • widget::Image now computes the layout correctly when unbound in one direction. ([#1189] by [@JAicewizard])
    • TextBox doesn't reset position after unfocused. ([#1276] by [@sysint64])
    • Able to select text in multiple TextBoxes at once. ([#1276] by [@sysint64])
    • The scroll bar now shows when the contents of a scrollable area change size. ([#1278] by [@Majora320])
    • ๐Ÿ›  Fix widget::Either using the wrong paint insets ([#1299] by [@andrewhickman])
    • ๐Ÿ›  Various fixes to cross-platform menus ([#1306] by [@raphlinus])
    • ๐Ÿ‘Œ Improve Windows 7 DXGI compatibility ([#1311] by [@raphlinus])
    • ๐Ÿ›  Fixed Either not passing events to its hidden child correctly. ([#1351] by [@andrewhickman])
    • ๐Ÿ”Š Don't drop events while showing file dialogs ([#1302], [#1328] by [@jneem])
    • ๐Ÿ‘€ Ensure that LifeCycle::WidgetAdded is the first thing a widget sees. ([#1259] by [@finnerale])
    • ๐Ÿ›  Fix a missed call to CloseClipboard on Windows. ([#1410] by [@andrewhickman])
    • โš  WidgetPod: change not laid out debug_panic to warning ([#1441] by [@Maan2003])

    Visual

    • TextBox stroke remains inside its paint_rect. ([#1007] by [@jneem])

    ๐Ÿ“„ Docs

    • โž• Added a book chapter about resolution independence. ([#913] by [@xStrom])
    • โž• Added documentation for the Image widget. ([#1018] by [@covercash2])
    • ๐Ÿ›  Fixed a link in druid::command documentation. ([#1008] by [@covercash2])
    • ๐Ÿ›  Fixed broken links in druid::widget::Container documentation. ([#1357] by [@StarfightLP])

    Examples

    • Specify feature requirements in a standard way. ([#1050] by [@xStrom])
    • โž• Added event_viewer example ([#1326] by [@cmyr])
    • Rename ext_event to async_event. ([#1401] by [@JAicewizard])

    ๐Ÿšง Maintenance

    • ๐ŸŒ Standardized web targeting terminology. ([#1013] by [@xStrom])
    • X11: Ported the X11 backend to x11rb. ([#1025] by [@jneem])
    • โž• Add debug_panic macro for when a backtrace is useful but a panic unnecessary. ([#1259] by [@finnerale])

    Outside News


Previous changes from v0.6.0

  • Highlights

    X11 backend for druid-shell.

    ๐Ÿ‘ [@crsaracco] got us started and implemented basic support to run druid on bare-metal X11 in [#599]. โž• Additional features got fleshed out in [#894] and [#900] by [@xStrom] and in [#920], [#961], and [#982] by [@jneem].

    ๐Ÿง While still incomplete this lays the foundation for running druid on Linux without relying on GTK.

    ๐ŸŒ Web backend for druid-shell.

    ๐ŸŒ [@elrnv] continued the work of [@tedsta] and implemented a mostly complete web backend via WebAssembly (Wasm) in [#759] and enabled all druid examples to ๐Ÿ’ป run in the browser.

    ๐Ÿ”Š While some features like the clipboard, menus or file dialogs are not yet available, all fundamental features are there.

    ๐ŸŽ Using Core Graphics on macOS.

    ๐Ÿ‘ [@cmyr] continued the work of [@jrmuizel] and implemented Core Graphics support for Piet in piet#176.

    Those changes made it into druid via [#905]. ๐ŸŽ This means that druid no longer requires cairo on macOS and uses Core Graphics instead.

    โž• Added

    • Standardized and exposed more methods on more contexts. ([#970], [#972], [#855] by [@cmyr], [#898] by [@finnerale], [#954] by [@xStrom], [#917] by [@jneem])
    • ๐Ÿ“„ im feature, with Data support for the im crate collections. ([#924] by [@cmyr])
    • ๐Ÿ‘ im::Vector support for the List widget. ([#940] by [@xStrom])
    • TextBox can receive EditAction commands. ([#814] by [@cmyr])
    • Split::min_splitter_area(f64) to add padding around the splitter bar. ([#738] by [@xStrom])
    • Published druid::text module. ([#816] by [@cmyr])
    • ๐Ÿšฆ InternalEvent::MouseLeave signalling the cursor left the window. ([#821] by [@teddemunnik])
    • InternalEvent::RouteTimer to route timer events. ([#831] by [@sjoshid])
    • children_changed now always includes layout and paint request. ([#839] by [@xStrom])
    • request_paint_rect for partial invalidation. ([#817] by [@jneem])
    • Window title can be any LabelText (such as a simple String). ([#869] by [@cmyr])
    • Label::with_font and set_font. ([#785] by [@thecodewarrior])
    • ๐ŸŽ MouseEvent now has a focus field which is true with window focusing left clicks on macOS. ([#842] by [@xStrom])
    • ๐Ÿ‘€ MouseButtons to MouseEvent to track which buttons are being held down during an event. ([#843] by [@xStrom])
    • Env and Key gained methods for inspecting an Env at runtime ([#880] by [@Zarenor])
    • WinHandler::scale method to inform of scale changes. ([#904] by [@xStrom])
    • WidgetExt::debug_widget_id, for displaying widget ids on hover. ([#876] by [@cmyr])
    • LifeCycle::Size event to inform widgets that their size changed. ([#953] by [@xStrom])
    • FileDialogOptions methods default_name, name_label, title, button_text, packages_as_directories, force_starting_directory. ([#960] by [@xStrom])
    • Button::dynamic constructor. ([#963] by [@totsteps])
    • Spinner widget to represent loading states. ([#1003] by [@futurepaul])
    • ๐Ÿ”— Link to the widget_nursery in README ([#1754] by [@xarvic])

    ๐Ÿ”„ Changed

    • Renamed WidgetPod methods: paint to paint_raw, paint_with_offset to paint, paint_with_offset_always to paint_always. ([#980] by [@totsteps])
    • ๐Ÿšš Renamed Event::MouseMoved to MouseMove. ([#825] by [@teddemunnik])
    • ๐Ÿ“‡ Renamed Split constructors to Split::rows and columns. ([#738] by [@xStrom])
    • Replaced NEW_WINDOW, SET_MENU and SHOW_CONTEXT_MENU commands with methods on EventCtx and DelegateCtx. ([#931] by [@finnerale])
    • Replaced Command::one_shot and ::take_object with a SingleUse payload wrapper type. ([#959] by [@finnerale])
    • Command and Selector have been reworked and are now statically typed, similarly to Env and Key. ([#993] by [@finnerale])
    • AppDelegate::command now receives a Target instead of a &Target. ([#909] by [@xStrom])
    • SHOW_WINDOW and CLOSE_WINDOW commands now only use Target to determine the affected window. ([#928] by [@finnerale])
    • Global Application associated functions are instance methods instead, e.g. Application::global().quit() instead of the old Application::quit(). ([#763] by [@xStrom])
    • Event::Internal(InternalEvent) bundles all internal events. ([#833] by [@xStrom])
    • Timer events will only be delivered to the widgets that requested them. ([#831] by [@sjoshid])
    • Split::splitter_size no longer includes padding. ([#738] by [@xStrom])
    • has_focus no longer returns false positives. ([#819] by [@xStrom])
    • WidgetPod::set_layout_rect now requires LayoutCtx, data and Env. ([#841] by [@xStrom])
    • request_timer uses Duration instead of Instant. ([#847] by [@finnerale])
    • ๐Ÿ‘€ Event::Wheel now contains a MouseEvent structure. ([#895] by [@teddemunnik])
    • The WindowHandle::get_dpi method got replaced by WindowHandle::get_scale. ([#904] by [@xStrom])
    • The WinHandler::size method now gets a Size in display points. ([#904] by [@xStrom])
    • Standardized the type returned by the contexts' text methods. ([#996] by [@cmyr])
    • ViewSwitcher uses Data type constraint instead of PartialEq. ([#1112] by [@justinmoon])

    โœ‚ Removed

    • ๐Ÿง The optional GTK feature for non-Linux platforms. ([#611] by [@pyroxymat])

    ๐Ÿ›  Fixed

    • Event::HotChanged(false) will be emitted when the cursor leaves the window. ([#821] by [@teddemunnik])
    • Keep hot state consistent with mouse position. ([#841] by [@xStrom])
    • Start focus cycling from not-registered-for-focus widgets. ([#819] by [@xStrom])
    • Supply correct LifeCycleCtx to Event::FocusChanged. ([#878] by [@cmyr])
    • Propagate Event::FocusChanged to focus gaining widgets as well. ([#819] by [@xStrom])
    • Routing LifeCycle::FocusChanged to descendant widgets. ([#925] by [@yrns])
    • Focus request handling is now predictable with the last request overriding earlier ones. ([#948] by [@xStrom])
    • Open file menu item works again. ([#851] by [@kindlychung])
    • Built-in open and save menu items now show the correct label and submit the right commands. ([#930] by [@finnerale])
    • โšก๏ธ Wheel events now properly update hot state. ([#951] by [@xStrom])
    • ๐ŸŽ macOS: Support FileDialogOptions::default_type. ([#960] by [@xStrom])
    • macOS: Show the save dialog even with FileDialogOptions select_directories and multi_selection set. ([#960] by [@xStrom])
    • ๐Ÿ‘ X11: Support mouse scrolling. ([#961] by [@jneem])
    • Painter now properly repaints on data change in Container. ([#991] by [@cmyr])
    • ๐Ÿ Windows: Terminate app when all windows have closed. ([#763] by [@xStrom])
    • ๐Ÿ Windows: Respect the minimum window size. ([#727] by [@teddemunnik])
    • ๐Ÿ Windows: Respect resizability. ([#712] by [@teddemunnik])
    • ๐Ÿ Windows: Capture mouse for drag actions. ([#695] by [@teddemunnik])
    • ๐Ÿ Windows: Removed flashes of white background at the edge of the window when resizing. ([#915] by [@xStrom])
    • ๐Ÿ Windows: Reduced chance of white flash when opening a new window. ([#916] by [@xStrom])
    • ๐Ÿ Windows: Keep receiving mouse events after pressing ALT or F10 when the window has no menu. ([#997] by [@xStrom])
    • ๐ŸŽ macOS: Application::quit now quits the run loop instead of killing the process. ([#763] by [@xStrom])
    • ๐ŸŽ macOS: Event::HotChanged is properly generated with multiple windows. ([#907] by [@xStrom])
    • ๐ŸŽ macOS: The application menu is now immediately interactable after launch. ([#994] by [@xStrom])
    • ๐ŸŽ macOS/GTK: MouseButton::X1 and MouseButton::X2 clicks are now recognized. ([#843] by [@xStrom])
    • GTK: Use the system locale. ([#798] by [@finnerale])
    • ๐Ÿ GTK: Actually close windows. ([#797] by [@finnerale])
    • GTK: Prevent crashing on pop-ups. ([#837] by [@finnerale])
    • ๐Ÿ‘ GTK: Support disabled menu items. ([#897] by [@jneem])
    • ๐Ÿ”Š GTK: Support file filters in open/save dialogs. ([#903] by [@jneem])
    • ๐Ÿ‘ GTK: Support DPI values other than 96. ([#904] by [@xStrom])

    Visual

    • ๐Ÿ‘Œ Improved Split accuracy. ([#738] by [@xStrom])
    • Built-in widgets no longer stroke outside their paint_rect. ([#861] by [@jneem])
    • Switch toggles with animation when its data changes externally. ([#898] by [@finnerale])
    • Render progress bar correctly. ([#949] by [@scholtzan])
    • Scrollbars animate when the scroll container size changes. ([#964] by [@xStrom])

    ๐Ÿ“„ Docs

    • โž• Added example and usage hints to Env. ([#796] by [@finnerale])
    • โž• Added documentation about the usage of bloom filters. ([#818] by [@xStrom])
    • โž• Added book chapters about Painter and Controller. ([#832] by [@cmyr])
    • โž• Added a changelog containing development since the 0.5 release. ([#889] by [@finnerale])
    • โž• Added goals section to README.md. ([#971] by [@finnerale])
    • โž• Added a section about dependencies to CONTRIBUTING.md. ([#990] by [@xStrom])
    • โšก๏ธ Updated screenshots in README.md. ([#967] by [@xStrom])
    • โœ‚ Removed references to cairo on macOS. ([#943] by [@xStrom])

    Examples

    • โž• Added blocking_function. ([#840] by [@mastfissh])
    • โž• Added hot glow option to multiwin. ([#845] by [@xStrom])
    • โฌ‡๏ธ Reduce the flashing in ext_event and identity. ([#782] by [@futurepaul])
    • ๐Ÿ›  Fixed menu inconsistency across multiple windows in multiwin. ([#926] by [@kindlychung])

    ๐Ÿšง Maintenance

    • โž• Added rendering tests. ([#784] by [@fishrockz])
    • โž• Added docs generation testing for all features. ([#942] by [@xStrom])
    • Replaced #[macro_use] with normal use. ([#808] by [@totsteps])
    • Enabled Clippy checks for all targets. ([#850] by [@xStrom])
    • โšก๏ธ Revamped CI testing to optimize coverage and speed. ([#857] by [@xStrom])
    • ๐Ÿ”จ Refactored DPI scaling. ([#904] by [@xStrom])
    • ๐ŸŽ Refactored WidgetPod::event to improve readability and performance of more complex logic. ([#1001] by [@xStrom])
    • ๐Ÿ“‡ Renamed BaseState to WidgetState ([#969] by [@cmyr])
    • ๐Ÿ›  Fixed test harness crashing on failure. ([#984] by [@xStrom])
    • ๐Ÿ”จ GTK: Refactored Application to use the new structure. ([#892] by [@xStrom])

    Outside News

    • There are new projects using druid:
      • Kondo Save disk space by cleaning unneeded files from software projects.
      • jack-mixer A jack client that provides mixing, levels and a 3-band eq.
      • kiro-synth An in progress modular sound synthesizer.