Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
scroll_adjustments_invalidate_the_viewport_snapshot --locked --offline
GTK_A11Y=none \
GSK_RENDERER=cairo \
xvfb-run -a cargo test -p onenote-viewer navigation::tests --locked --offline
xvfb-run -a cargo test -p onenote-viewer --locked --offline
./scripts/package-native-release.sh

- name: Smoke-test quick-run executable
Expand Down
72 changes: 62 additions & 10 deletions crates/onenote-viewer/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,21 +409,13 @@ impl Viewer {
NOTEBOOK_NAVIGATION_WIDTH + PAGE_NAVIGATION_WIDTH + NAVIGATION_SEPARATOR_WIDTH;
navigation_stack.set_width_request(initial_navigation_width);

let page_title = gtk::Label::builder()
.xalign(0.0)
.ellipsize(gtk::pango::EllipsizeMode::End)
.build();
page_title.add_css_class("page-title");
let page_title = selectable_page_header_label("page-title");
let page_date = gtk::Label::builder()
.xalign(0.0)
.ellipsize(gtk::pango::EllipsizeMode::End)
.build();
page_date.add_css_class("page-date");
let page_context = gtk::Label::builder()
.xalign(0.0)
.ellipsize(gtk::pango::EllipsizeMode::End)
.build();
page_context.add_css_class("page-context");
let page_context = selectable_page_header_label("page-context");
let title_box = gtk::Box::new(gtk::Orientation::Vertical, 2);
title_box.set_margin_start(20);
title_box.set_margin_end(16);
Expand Down Expand Up @@ -2033,6 +2025,16 @@ fn result_list(model: &gtk::StringList) -> (gtk::SingleSelection, gtk::ListView)
(selection, list)
}

fn selectable_page_header_label(css_class: &str) -> gtk::Label {
let label = gtk::Label::builder()
.xalign(0.0)
.ellipsize(gtk::pango::EllipsizeMode::End)
.selectable(true)
.build();
label.add_css_class(css_class);
label
}

fn bind_string(item: &glib::Object, multiline: bool) {
let item = item.downcast_ref::<gtk::ListItem>().expect("list item");
let string = item
Expand Down Expand Up @@ -2762,6 +2764,56 @@ mod tests {
assert_eq!(notifications.get(), 2);
}

#[test]
fn page_header_label_copies_complete_ellipsized_unicode_text() {
crate::test_support::run_gtk_test(
page_header_label_copies_complete_ellipsized_unicode_text_gtk,
);
}

fn page_header_label_copies_complete_ellipsized_unicode_text_gtk() {
let text = "A long Unicode page title: Matematyka, Ελληνικά, 日本語, 😀";
let label = selectable_page_header_label("page-title");
label.set_label(text);
assert!(label.is_selectable());
assert!(label.is_focusable());
assert_eq!(label.ellipsize(), gtk::pango::EllipsizeMode::End);

let window = gtk::Window::builder()
.default_width(180)
.default_height(48)
.child(&label)
.build();
window.present();
while glib::MainContext::default().iteration(false) {}

assert!(label.grab_focus());
label
.activate_action("selection.select-all", None)
.expect("select-all action");
assert_eq!(
label.selection_bounds(),
Some((
0,
i32::try_from(text.chars().count()).expect("test text length")
))
);
label
.activate_action("clipboard.copy", None)
.expect("copy action");

let clipboard = label.clipboard();
let copied = glib::MainContext::default()
.block_on(clipboard.read_text_future())
.expect("read clipboard")
.expect("clipboard text");
assert_eq!(copied, text);

label.set_label("Next page");
assert_eq!(label.selection_bounds(), None);
window.close();
}

#[test]
fn both_themes_define_complete_control_and_selection_states() {
for theme in [EffectiveTheme::Light, EffectiveTheme::Dark] {
Expand Down
13 changes: 13 additions & 0 deletions docs/specs/desktop-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ Standard window-control fallbacks and the application icon are bundled so the
native, AppImage, and Flatpak headers do not depend on different host icon
inventories.

## Page Context Header

The page title and complete notebook/section-group/section context are
selectable application text. Pointer selection, the standard label context
menu, `Ctrl+A`, and `Ctrl+C` use GTK's native label behavior and must not
change the active notebook, section, or page. Visual end ellipsizing may
constrain the header layout, but selecting all and copying preserves the
complete underlying Unicode value.

The page date may remain display-only. Selection inside the freeform page
canvas is a separate renderer capability and is not implemented through these
header labels.

## Link Interaction

Explicit OneNote hyperlinks are always underlined. The persisted **Detect
Expand Down
Loading