From 0a42dcf073f512cf78be30d80117be9da8337fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 15 May 2024 13:13:30 -0700 Subject: [PATCH 1/3] CI: build against OS (#380) --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fe641970..6f57f01a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,30 @@ on: - synchronize jobs: + build: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + version: [stable, unstable, development-target] + container: + image: ghcr.io/elementary/docker:${{ matrix.version }} + + steps: + - uses: actions/checkout@v4 + - name: Install Dependencies + run: | + apt update + apt install -y libchamplain-0.12-dev libchamplain-gtk-0.12-dev libclutter-1.0-dev libclutter-gtk-1.0-dev libecal2.0-dev libedataserver1.2-dev libgeoclue-2-dev libgeocode-glib-dev libgdata-dev libgranite-dev libgtk-3-dev libhandy-1-dev libical-dev libportal-dev libportal-gtk3-dev meson valac + - name: Build and Test + env: + DESTDIR: out + run: | + meson setup build + ninja -C build install + ninja -C build test + flatpak: name: Flatpak runs-on: ubuntu-latest From 04a98b74fd1504c7ade85d9422631fb911e9396c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 16 May 2024 00:02:00 -0700 Subject: [PATCH 2/3] TaskRow: GTK4 Prep (#381) * Simple API changes * KeyController * frame child --- data/Application.css | 4 +++ src/Widgets/TaskRow.vala | 76 ++++++++++++++++++++++++---------------- 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/data/Application.css b/data/Application.css index 73a95d959..efd754381 100644 --- a/data/Application.css +++ b/data/Application.css @@ -67,6 +67,10 @@ row.task.drag-active { transition: none; } +.button-box button { + min-width: 86px; /* https://github.com/elementary/granite/issues/577#issuecomment-1318979272 */ +} + .source-color { background: @colorAccent; border: 1px solid @borders; diff --git a/src/Widgets/TaskRow.vala b/src/Widgets/TaskRow.vala index e57a3af11..a40f51024 100644 --- a/src/Widgets/TaskRow.vala +++ b/src/Widgets/TaskRow.vala @@ -35,6 +35,8 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { private Gtk.Revealer task_form_revealer; private Gtk.TextBuffer description_textbuffer; + private Gtk.EventControllerKey key_controller; + private TaskRow (ECal.Component task, E.Source source) { Object (task: task, source: source); } @@ -88,11 +90,11 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { } due_datetime_popover_revealer = new Gtk.Revealer () { + child = due_datetime_popover, margin_end = 6, reveal_child = false, - transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT + transition_type = SLIDE_RIGHT }; - due_datetime_popover_revealer.add (due_datetime_popover); due_datetime_popover.value_format.connect ((value) => { due_datetime_popover.get_style_context ().remove_class ("error"); @@ -140,11 +142,11 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { location_popover = new Tasks.Widgets.EntryPopover.Location (); location_popover_revealer = new Gtk.Revealer () { + child = location_popover, margin_end = 6, reveal_child = false, - transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT + transition_type = SLIDE_RIGHT }; - location_popover_revealer.add (location_popover); location_popover.value_format.connect ((value) => { if (value == null) { @@ -182,23 +184,26 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { // Should not use a transition that varies the width else label aligning and ellipsizing is incorrect. description_label_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.CROSSFADE, + child = description_label, + transition_type = CROSSFADE, reveal_child = false }; - description_label_revealer.add (description_label); - var task_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); + var task_box = new Gtk.Box (HORIZONTAL, 0); task_box.add (due_datetime_popover_revealer); task_box.add (location_popover_revealer); task_box.add (description_label_revealer); task_detail_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.SLIDE_UP + child = task_box, + transition_type = SLIDE_UP }; - task_detail_revealer.add (task_box); var description_textview = new Granite.HyperTextView () { - border_width = 12, + top_margin = 12, + right_margin = 12, + bottom_margin = 12, + left_margin = 12, height_request = 140, accepts_tab = false }; @@ -208,25 +213,30 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { description_textview.set_buffer (description_textbuffer); var description_frame = new Gtk.Frame (null) { + child = description_textview, hexpand = true }; - description_frame.add (description_textview); var cancel_button = new Gtk.Button.with_label (_("Cancel")); var save_button = new Gtk.Button.with_label (created ? _("Save Changes") : _("Add Task")); save_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - var button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL) { - baseline_position = Gtk.BaselinePosition.CENTER, - margin_top = 12, - spacing = 6 + var right_buttons_box = new Gtk.Box (HORIZONTAL, 6) { + hexpand = true, + halign = END, + homogeneous = true }; - button_box.set_layout (Gtk.ButtonBoxStyle.END); - button_box.add (cancel_button); - button_box.add (save_button); + right_buttons_box.add (cancel_button); + right_buttons_box.add (save_button); - var form_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12) { + var button_box = new Gtk.Box (HORIZONTAL, 6) { + margin_top = 12 + }; + button_box.get_style_context ().add_class ("button-box"); + button_box.pack_end (right_buttons_box); + + var form_box = new Gtk.Box (VERTICAL, 12) { margin_top = 6, margin_bottom = 6 }; @@ -234,9 +244,9 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { form_box.add (button_box); task_form_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN + child = form_box, + transition_type = SLIDE_DOWN }; - task_form_revealer.add (form_box); var grid = new Gtk.Grid () { margin_top = 6, @@ -252,10 +262,10 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { grid.attach (task_form_revealer, 1, 2); revealer = new Gtk.Revealer () { - reveal_child = true + child = grid, + reveal_child = true, + transition_type = SLIDE_UP }; - revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_UP; - revealer.add (grid); event_box = new Gtk.EventBox () { hexpand = true, @@ -268,8 +278,9 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { ); event_box.add (revealer); - add (event_box); - margin_start = margin_end = 12; + child = event_box; + margin_start = 12; + margin_end = 12; get_style_context ().add_class ("task"); get_style_context ().add_class (Granite.STYLE_CLASS_ROUNDED); @@ -278,11 +289,12 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { check.show (); state_stack.visible_child = check; - var delete_button = new Gtk.Button.with_label (_("Delete Task")); + var delete_button = new Gtk.Button.with_label (_("Delete Task")) { + halign = START + }; delete_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); - button_box.add (delete_button); - button_box.set_child_secondary (delete_button, true); + button_box.pack_start (delete_button); delete_button.clicked.connect (() => { end_editing (); @@ -293,6 +305,8 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { build_drag_and_drop (); + key_controller = new Gtk.EventControllerKey (this); + check.toggled.connect (() => { if (task == null) { return; @@ -316,8 +330,8 @@ public class Tasks.Widgets.TaskRow : Gtk.ListBoxRow { end_editing (); }); - key_release_event.connect ((event) => { - if (event.keyval == Gdk.Key.Escape) { + key_controller.key_released.connect ((keyval, keycode, state) => { + if (keyval == Gdk.Key.Escape) { reset_form (); end_editing (); } From a510b0c6349cd25fed55c6294d2a22da089aa250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 16 May 2024 00:53:07 -0700 Subject: [PATCH 3/3] MainWindow: Gtk4 prep (#378) Co-authored-by: Leo --- src/MainWindow.vala | 79 ++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 9b6219129..65cc3c208 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -21,7 +21,7 @@ public class Tasks.MainWindow : Hdy.ApplicationWindow { private Gee.HashMap? source_rows; private Gee.Collection? collection_sources; private Gtk.Stack task_list_grid_stack; - private Gtk.ButtonBox add_tasklist_buttonbox; + private Gtk.Box add_tasklist_buttonbox; public MainWindow (Gtk.Application application) { Object ( @@ -72,62 +72,66 @@ public class Tasks.MainWindow : Hdy.ApplicationWindow { listbox.add (scheduled_row); var scrolledwindow = new Gtk.ScrolledWindow (null, null) { + child = listbox, hexpand = true, vexpand = true, hscrollbar_policy = Gtk.PolicyType.NEVER }; - scrolledwindow.add (listbox); - add_tasklist_buttonbox = new Gtk.ButtonBox (Gtk.Orientation.VERTICAL) { - layout_style = Gtk.ButtonBoxStyle.EXPAND - }; + add_tasklist_buttonbox = new Gtk.Box (VERTICAL, 3); var online_accounts_button = new Gtk.ModelButton () { text = _("Online Accounts Settings…") }; - var add_tasklist_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 3) { + var add_tasklist_box = new Gtk.Box (VERTICAL, 3) { margin_top = 3, margin_bottom = 3 }; add_tasklist_box.add (add_tasklist_buttonbox); - add_tasklist_box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); + add_tasklist_box.add (new Gtk.Separator (HORIZONTAL)); add_tasklist_box.add (online_accounts_button); add_tasklist_box.show_all (); - var add_tasklist_popover = new Gtk.Popover (null); - add_tasklist_popover.add (add_tasklist_box); + var add_tasklist_popover = new Gtk.Popover (null) { + child = add_tasklist_box + }; + + var add_list_label = new Gtk.Label (_("Add Task List…")); + + var add_list_button_box = new Gtk.Box (HORIZONTAL, 0); + add_list_button_box.add (new Gtk.Image.from_icon_name ("list-add-symbolic", SMALL_TOOLBAR)); + add_list_button_box.add (add_list_label); var add_tasklist_button = new Gtk.MenuButton () { - label = _("Add Task List…"), - image = new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR), - always_show_image = true, + child = add_list_button_box, popover = add_tasklist_popover }; + add_list_label.mnemonic_widget = add_tasklist_button; + var actionbar = new Gtk.ActionBar (); actionbar.add (add_tasklist_button); actionbar.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); - var sidebar = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + var sidebar = new Gtk.Box (VERTICAL, 0); sidebar.get_style_context ().add_class (Gtk.STYLE_CLASS_SIDEBAR); sidebar.add (sidebar_header); sidebar.add (scrolledwindow); sidebar.add (actionbar); - task_list_grid_stack = new Gtk.Stack (); - var main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + var main_box = new Gtk.Box (VERTICAL, 0); main_box.get_style_context ().add_class (Gtk.STYLE_CLASS_BACKGROUND); main_box.add (main_header); main_box.add (task_list_grid_stack); - var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL); + var paned = new Gtk.Paned (HORIZONTAL); paned.pack1 (sidebar, false, false); paned.pack2 (main_box, true, false); - add (paned); + child = paned; delete_event.connect (() => { ((Application)application).request_background.begin (() => destroy ()); @@ -284,8 +288,8 @@ public class Tasks.MainWindow : Hdy.ApplicationWindow { transient_for = this }; error_dialog.show_error_details (error_message); - error_dialog.run (); - error_dialog.destroy (); + error_dialog.present (); + error_dialog.response.connect (error_dialog.destroy); return GLib.Source.REMOVE; }); @@ -309,23 +313,26 @@ public class Tasks.MainWindow : Hdy.ApplicationWindow { unowned Gtk.Widget trash_button = message_dialog.add_button (_("Delete Anyway"), Gtk.ResponseType.YES); trash_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); - Gtk.ResponseType response = (Gtk.ResponseType) message_dialog.run (); - message_dialog.destroy (); - - if (response == Gtk.ResponseType.YES) { - Tasks.Application.model.remove_task_list.begin (source, (obj, res) => { - try { - Tasks.Application.model.remove_task_list.end (res); - } catch (Error e) { - critical (e.message); - show_error_dialog ( - _("Deleting the task list failed"), - _("The task list registry may be unavailable or unable to be written to."), - e - ); - } - }); - } + message_dialog.response.connect ((response) => { + if (response == Gtk.ResponseType.YES) { + Tasks.Application.model.remove_task_list.begin (source, (obj, res) => { + try { + Tasks.Application.model.remove_task_list.end (res); + } catch (Error e) { + critical (e.message); + show_error_dialog ( + _("Deleting the task list failed"), + _("The task list registry may be unavailable or unable to be written to."), + e + ); + } + }); + } + + message_dialog.destroy (); + }); + + message_dialog.present (); } else { Gdk.beep ();