╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │2496 // the labels view's flow inside the stack. │ │2497 fn labelsView(self: *This) *WordFlow { │ │2498 return &self.viewStack().children.values()[labels_view_index].word_flow;│ │2499 + } │ │2500 + │ │2501 + // no labels and no filter to clear, which shows the empty message │ │2502 + fn labelsEmpty(data: *const Self) bool { │ │2503 + return data.label.len == 0 and data.labels.len == 0; │ │2504 } │ │2505 │ │2506 // the non-confirmation form inside the stack │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2574 if (supports_conflicts and index == conflict_view_index) return &self.data.conflicts;│ │2575 if (supports_drafts and index == drafts_view_index) return &self.data.drafts; │ │2576 return self.data.window(splitStatus(index)); │ │2577 + } │ │2578 + │ │2579 + // an empty first window, which shows the empty message │ │2580 + fn windowEmpty(win: *const Window) bool { │ │2581 + return win.items.len == 0 and win.prev_id == null; │ │2582 } │ │2583 │ │2584 fn stackSelectedIndex(self: *This) ?usize { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2587 return stack.children.getIndex(cid); │ │2588 } │ │2589 │ │2575 - // the stack's selected master-detail split (null when the labels view or the │ │2576 - // new-thread form shows). │ │2590 + // the stack's selected master-detail split (null when the labels view, the │ │2591 + // new-thread form, or the empty message shows). │ │2592 fn selectedSplitIndex(self: *This) ?usize { │ │2593 const idx = self.stackSelectedIndex() orelse return null; │ │2579 - return if (idx < status_count or (supports_drafts and idx == drafts_view_index) or idx == conflict_view_index) idx else null;│ │2594 + const split = idx < status_count or (supports_drafts and idx == drafts_view_index) or idx == conflict_view_index; │ │2595 + return if (split and !windowEmpty(self.window(idx))) idx else null; │ │2596 } │ │2597 │ │2598 fn detailActive(self: *This, index: usize) bool { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2723 // view has something to focus; enter in the search box submits │ │2724 // the query; other keys move within the sub-header. │ │2725 if (inp.vertDirection(key) == .down) { │ │2710 - const enterable = if (self.viewStack().getSelected()) |selected| switch (selected.*) {│ │2711 - .word_flow => |*tf| tf.text_boxes.items.len > 0, │ │2712 - // nothing focusable in the unauthorized view │ │2713 - .unauthorized => false, │ │2714 - else => true, │ │2715 - } else false; │ │2726 + const enterable = if (self.stackSelectedIndex()) |idx| │ │2727 + if (idx == labels_view_index) │ │2728 + !labelsEmpty(self.data) │ │2729 + else if (idx == form_view_index) │ │2730 + // nothing focusable in the unauthorized view │ │2731 + self.viewStack().children.values()[idx] != .unauthorized │ │2732 + else │ │2733 + !windowEmpty(self.window(idx)) │ │2734 + else │ │2735 + false; │ │2736 if (enterable) root_focus.setFocus(self.box.children.keys()[stack_index]); │ │2737 } else if (key == .enter) { │ │2738 if (try self.header().submittedText(allocator)) |submission| { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯