nandi/jolt-nativepublic Fork 0
6316bb1
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Put a row's `:align :end` where the row ends

`align` on a row was read as a cross-axis gravity and handed to
`align_y`, which is what a column's `align` means and not what a row's
does. glimmer's meaning — the one the shared screens and frq.hiccup are
written against — is the main axis: `:end` lays the children out *from*
the right, so the first child in the source is the rightmost on screen.

Taken as a gravity it did nothing you could see except sit the children
low. frq's message heading is where that showed: its two chips came out
hard against the clock, in the order ✏️ ↩️ 🙂 rather than the other way
round against the right edge, and the words below lost the width the
chips took. The chats screen's join and search rows had the same silent
no-op.

iced has no main-axis alignment on a Row, so the edge is a container's
doing: the children reversed, and the row put against the right of a
container that takes the width. Not a leading Fill space, which would
have halved the slack with a row that already has something filling in
it — the join box beside its button is exactly that row, and the box is
meant to take all of it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-12T10:22:03-07:00 Browse files
6316bb1 parent: 5ba95e0
modified crates/jolt-cosmic/src/lib.rs +36 -7
@@ -32,6 +32,7 @@ use std::sync::{Arc, Condvar, LazyLock, Mutex, MutexGuard};
3232 use std::time::Duration;
3333
3434 use cosmic::app::{Core, Task};
35+use cosmic::iced::alignment::Horizontal;
3536 use cosmic::iced::futures::channel::mpsc;
3637 use cosmic::iced::futures::{Stream, StreamExt};
3738 use cosmic::iced::widget::container::Style as ContainerStyle;
@@ -857,9 +858,10 @@ fn width_request(n: &Node) -> Option<f32> {
857858 n.num("width-request").filter(|w| *w > 0.0).map(|w| w as f32)
858859 }
859860
860-/// `align`, or `default` where it is not set. A row centres its children on
861-/// the cross axis by default — a label beside a button otherwise sits against
862-/// the top of the button — and a column starts them at the left.
861+/// `align`, or `default` where it is not set. A column starts its children at
862+/// the left. Rows do not ask: `align` on a row is where along the row its
863+/// children sit, not how they line up across it, and the row branch of
864+/// `element` reads it itself.
863865 fn alignment(n: &Node, default: Alignment) -> Alignment {
864866 match n.str("align") {
865867 "start" => Alignment::Start,
@@ -950,10 +952,25 @@ fn element(t: &Tree, id: i32, enabled: bool, in_row: bool) -> Element<'_, Messag
950952 "box" => {
951953 let across = n.str("orientation") == "horizontal";
952954 if across {
953- let mut row = Row::with_children(children(true))
954- .spacing(spacing)
955- .padding(margins(n))
956- .align_y(alignment(n, Alignment::Center));
955+ // `align` on a row is the MAIN axis, which is glimmer's
956+ // meaning and the one the shared screens are written against:
957+ // `:end` lays the children out *from* the right, so the first
958+ // child in the source is the rightmost on screen. Read as a
959+ // cross-axis gravity instead it did nothing visible but sit
960+ // the chips low, and the message heading's pair came out in
961+ // the order ✏️ ↩️ 🙂 hard against the clock rather than the
962+ // other way round against the edge — see `chat/action-chips`.
963+ let from_end = n.str("align") == "end";
964+ let mut row = if from_end {
965+ Row::with_children(children(true).collect::<Vec<_>>().into_iter().rev())
966+ } else {
967+ Row::with_children(children(true))
968+ }
969+ .spacing(spacing)
970+ .padding(margins(n))
971+ // Across the row the children still centre: a chip beside a
972+ // label sitting against the top of it is what that is for.
973+ .align_y(Alignment::Center);
957974 // A row fills the width it is in only when it or something in
958975 // it asks to; otherwise a line of buttons would spread out.
959976 match width_request(n) {
@@ -964,6 +981,18 @@ fn element(t: &Tree, id: i32, enabled: bool, in_row: bool) -> Element<'_, Messag
964981 if fill_height {
965982 row = row.height(Length::Fill);
966983 }
984+ if from_end {
985+ // iced has no main-axis alignment on a Row, so the edge is
986+ // a container's doing: it takes the width and puts the row
987+ // against the right of it. Not a leading Fill space, which
988+ // would have halved the slack with a row that already has
989+ // something filling in it — the join box beside its button
990+ // is that row, and the box is meant to take all of it.
991+ return widget::container(row)
992+ .width(Length::Fill)
993+ .align_x(Horizontal::Right)
994+ .into();
995+ }
967996 row.into()
968997 } else {
969998 let mut column = Column::with_children(children(false))
@@ -32,6 +32,7 @@ use std::sync::{Arc, Condvar, LazyLock, Mutex, MutexGuard};
32 use std::time::Duration;32 use std::time::Duration;
33 33
34 use cosmic::app::{Core, Task};34 use cosmic::app::{Core, Task};
35+use cosmic::iced::alignment::Horizontal;
35 use cosmic::iced::futures::channel::mpsc;36 use cosmic::iced::futures::channel::mpsc;
36 use cosmic::iced::futures::{Stream, StreamExt};37 use cosmic::iced::futures::{Stream, StreamExt};
37 use cosmic::iced::widget::container::Style as ContainerStyle;38 use cosmic::iced::widget::container::Style as ContainerStyle;
@@ -857,9 +858,10 @@ fn width_request(n: &Node) -> Option<f32> {
857 n.num("width-request").filter(|w| *w > 0.0).map(|w| w as f32)858 n.num("width-request").filter(|w| *w > 0.0).map(|w| w as f32)
858 }859 }
859 860
860-/// `align`, or `default` where it is not set. A row centres its children on861+/// `align`, or `default` where it is not set. A column starts its children at
861-/// the cross axis by default — a label beside a button otherwise sits against862+/// the left. Rows do not ask: `align` on a row is where along the row its
862-/// the top of the button — and a column starts them at the left.863+/// children sit, not how they line up across it, and the row branch of
864+/// `element` reads it itself.
863 fn alignment(n: &Node, default: Alignment) -> Alignment {865 fn alignment(n: &Node, default: Alignment) -> Alignment {
864 match n.str("align") {866 match n.str("align") {
865 "start" => Alignment::Start,867 "start" => Alignment::Start,
@@ -950,10 +952,25 @@ fn element(t: &Tree, id: i32, enabled: bool, in_row: bool) -> Element<'_, Messag
950 "box" => {952 "box" => {
951 let across = n.str("orientation") == "horizontal";953 let across = n.str("orientation") == "horizontal";
952 if across {954 if across {
953- let mut row = Row::with_children(children(true))955+ // `align` on a row is the MAIN axis, which is glimmer's
954- .spacing(spacing)956+ // meaning and the one the shared screens are written against:
955- .padding(margins(n))957+ // `:end` lays the children out *from* the right, so the first
956- .align_y(alignment(n, Alignment::Center));958+ // child in the source is the rightmost on screen. Read as a
959+ // cross-axis gravity instead it did nothing visible but sit
960+ // the chips low, and the message heading's pair came out in
961+ // the order ✏️ ↩️ 🙂 hard against the clock rather than the
962+ // other way round against the edge — see `chat/action-chips`.
963+ let from_end = n.str("align") == "end";
964+ let mut row = if from_end {
965+ Row::with_children(children(true).collect::<Vec<_>>().into_iter().rev())
966+ } else {
967+ Row::with_children(children(true))
968+ }
969+ .spacing(spacing)
970+ .padding(margins(n))
971+ // Across the row the children still centre: a chip beside a
972+ // label sitting against the top of it is what that is for.
973+ .align_y(Alignment::Center);
957 // A row fills the width it is in only when it or something in974 // A row fills the width it is in only when it or something in
958 // it asks to; otherwise a line of buttons would spread out.975 // it asks to; otherwise a line of buttons would spread out.
959 match width_request(n) {976 match width_request(n) {
@@ -964,6 +981,18 @@ fn element(t: &Tree, id: i32, enabled: bool, in_row: bool) -> Element<'_, Messag
964 if fill_height {981 if fill_height {
965 row = row.height(Length::Fill);982 row = row.height(Length::Fill);
966 }983 }
984+ if from_end {
985+ // iced has no main-axis alignment on a Row, so the edge is
986+ // a container's doing: it takes the width and puts the row
987+ // against the right of it. Not a leading Fill space, which
988+ // would have halved the slack with a row that already has
989+ // something filling in it — the join box beside its button
990+ // is that row, and the box is meant to take all of it.
991+ return widget::container(row)
992+ .width(Length::Fill)
993+ .align_x(Horizontal::Right)
994+ .into();
995+ }
967 row.into()996 row.into()
968 } else {997 } else {
969 let mut column = Column::with_children(children(false))998 let mut column = Column::with_children(children(false))