From 44b66585242ba4b96c39acb49ea60344828b4182 Mon Sep 17 00:00:00 2001 From: Eva M Date: Sun, 12 Apr 2026 21:20:23 -0700 Subject: [PATCH 01/16] put progress bar behind the install button --- src/bazaar.gresource.xml | 1 + src/bz-install-controls.blp | 30 +++++++------ src/bz-install-controls.c | 24 ++++++++++ src/bz-install-controls.wdgt | 85 ++++++++++++++++++++++++++++++++++++ src/style.css | 10 +++++ 5 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 src/bz-install-controls.wdgt diff --git a/src/bazaar.gresource.xml b/src/bazaar.gresource.xml index 84c69d7a..56631948 100644 --- a/src/bazaar.gresource.xml +++ b/src/bazaar.gresource.xml @@ -207,6 +207,7 @@ icons/io.github.kolunmi.Bazaar.google.svg bz-global-progress.wdgt + bz-install-controls.wdgt diff --git a/src/bz-install-controls.blp b/src/bz-install-controls.blp index d2cc0db2..d36f15b6 100644 --- a/src/bz-install-controls.blp +++ b/src/bz-install-controls.blp @@ -2,38 +2,40 @@ using Gtk 4.0; using Adw 1; template $BzInstallControls: Box { - homogeneous: bind $invert_boolean(template.wide) as ; - spacing: bind $choose(template.wide, 10, 8) as ; hexpand: bind $invert_boolean(template.wide) as ; - valign: center; Stack { transition-type: crossfade; visible-child-name: bind $get_visible_page(template.entry-group as <$BzEntryGroup>.installable, template.entry-group as <$BzEntryGroup>.removable, template.state as <$BzStateInfo>.available-updates) as ; hexpand: bind $invert_boolean(template.wide) as ; hhomogeneous: false; + valign: center; StackPage install { name: "install"; - child: Button install_button { - styles [ - "suggested-action", - "pill", - ] - + child: $BgeWdgtRenderer install_button { margin-top: 3; margin-bottom: 3; margin-start: 3; margin-end: 3; + resource: "/io/github/kolunmi/Bazaar/bz-install-controls.wdgt"; + reference: bind template.state as <$BzStateInfo>; + + state: bind $get_install_btn_state( + template.state as <$BzStateInfo>.transaction-manager as <$BzTransactionManager>.active as , + template.state as <$BzStateInfo>.transaction-manager as <$BzTransactionManager>.pending as + ) as ; + has-tooltip: true; hexpand: bind $invert_boolean(template.wide) as ; halign: bind $choose(template.wide, 2, 0) as ; - sensitive: bind $invert_boolean($is_zero(template.entry-group as <$BzEntryGroup>.installable-and-available) as ) as ; - label: _("_Install"); - use-underline: true; - clicked => $install_cb(template); + // sensitive: bind $invert_boolean($is_zero(template.entry-group as <$BzEntryGroup>.installable-and-available) as ) as ; + + // label: _("_Install"); + // use-underline: true; + // clicked => $install_cb(template); }; } @@ -155,4 +157,4 @@ template $BzInstallControls: Box { child: Adw.Bin {}; } } -} \ No newline at end of file +} diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index 80a368e3..8cffd1cb 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -22,6 +22,8 @@ #include +#include + #include "bz-install-controls.h" #include "bz-state-info.h" #include "bz-template-callbacks.h" @@ -162,6 +164,19 @@ get_visible_page (gpointer object, return g_strdup ("empty"); } +static char * +get_install_btn_state (gpointer object, + gboolean active, + gboolean pending) +{ + if (pending) + return g_strdup ("pending"); + else if (active) + return g_strdup ("fraction"); + else + return g_strdup ("inactive"); +} + static gboolean is_blocked (gpointer object, GListModel *parental_blocked, @@ -325,15 +340,24 @@ bz_install_controls_class_init (BzInstallControlsClass *klass) gtk_widget_class_bind_template_callback (widget_class, run_cb); gtk_widget_class_bind_template_callback (widget_class, update_cb); gtk_widget_class_bind_template_callback (widget_class, get_visible_page); + gtk_widget_class_bind_template_callback (widget_class, get_install_btn_state); gtk_widget_class_bind_template_callback (widget_class, is_blocked); } static void bz_install_controls_init (BzInstallControls *self) { + g_autoptr (GtkWidget) btn = NULL; + self->wide = TRUE; gtk_widget_init_template (GTK_WIDGET (self)); + + btn = bge_wdgt_renderer_lookup_object ( + BGE_WDGT_RENDERER (self->install_button), "btn"); + g_signal_connect_swapped ( + btn, "clicked", + G_CALLBACK (install_cb), self); } GtkWidget * diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt new file mode 100644 index 00000000..3ab9e2e8 --- /dev/null +++ b/src/bz-install-controls.wdgt @@ -0,0 +1,85 @@ +defwidget "Install Button" { + reference state : "BzStateInfo"; + var progress : "gdouble"; + + var t : "BgeWdgtTime"; + var btn : "GtkButton"; + var bg : "GtkFixed"; + + var x : "gdouble"; + var w : "gdouble"; + var b : "gdouble"; + var opacity : "gdouble"; + + var final-x : "gdouble"; + var final-y : "gdouble"; + var final-w : "gdouble"; + var final-h : "gdouble"; + + init { + set progress = #transition(state:transaction-manager:current-progress, 1.1, 0.1, 10.0); + set t = #(notify-msec = 10;); + + set btn = #child/("" ("pill" "install-button") + use-underline = true; + ); + allocate btn %width%, %height%, #(); + + set bg = #child/("" ("install-button" "install-button-indicator") + opacity = opacity; + ); + + set final-w = #eval(#(w)-2.0*#(b)); + set final-h = #eval(#(%height%)-2.0*#(b)); + set final-x = #eval(#(x)+#(b)); + set final-y = b; + allocate bg final-w, final-h, #(translate(#GraphenePoint(final-x, final-y));); + + snapshot { + do-child bg; + do-child btn; + } + } + + state-default "inactive" { + set btn:label = "_Install"; + + set x = #eval((#(%width%)-#(w))/2.0); + set w = #eval(#(b)*2.0); + set b = #eval(#(%height%)/3.0); + set opacity = 0.0; + + transition-spring x 1.0, 0.1, 10.0; + transition-spring w 1.0, 0.1, 10.0; + transition-spring b 1.0, 0.1, 10.0; + transition-spring opacity 1.0, 0.1, 50.0; + } + + state "pending" { + set btn:label = "_Cancel"; + + set x = #eval((0.5+0.5*sin(3.0*#(t:time))) * (#(%width%)-#(w))); + set w = #eval(#(%width%)*0.8); + set b = #eval(#(%height%)*0.2); + set opacity = 1.0; + + transition-spring x 1.0, 0.1, 50.0; + transition-spring w 1.0, 0.1, 50.0; + transition-spring b 1.0, 0.1, 50.0; + transition-spring opacity 1.0, 0.1, 50.0; + } + + state "fraction" { + set btn:label = "_Cancel"; + + set x = 0.0; + set w = #eval(#(%height%)+(#(%width%)-#(%height%))*#(progress)); + set b = #eval(#(%height%)*0.1); + set opacity = 1.0; + + transition-spring x 1.1, 0.1, 100.0; + transition-spring w 1.1, 0.1, 100.0; + transition-spring b 1.1, 0.1, 100.0; + transition-spring opacity 1.1, 0.1, 10.0; + } +} diff --git a/src/style.css b/src/style.css index d04510c8..86df7c63 100644 --- a/src/style.css +++ b/src/style.css @@ -895,3 +895,13 @@ curated-list-view, curated-list-view list { background: var(--bg-color); } + + +.install-button { + background-color: alpha(var(--accent-bg-color), 0.333); + color: var(--accent-color); +} + +.install-button-indicator { + border-radius: 9999px; +} From 71cf0172568a0e100c47910acdaa817442b64697 Mon Sep 17 00:00:00 2001 From: Eva M Date: Mon, 13 Apr 2026 01:09:09 -0700 Subject: [PATCH 02/16] use GtkStack instead of changing label text --- src/bz-install-controls.wdgt | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index 3ab9e2e8..cc62f7ed 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -6,6 +6,10 @@ defwidget "Install Button" { var btn : "GtkButton"; var bg : "GtkFixed"; + var stack : "GtkStack"; + var install-label : "GtkLabel"; + var cancel-label : "GtkLabel"; + var x : "gdouble"; var w : "gdouble"; var b : "gdouble"; @@ -20,8 +24,16 @@ defwidget "Install Button" { set progress = #transition(state:transaction-manager:current-progress, 1.1, 0.1, 10.0); set t = #(notify-msec = 10;); + set stack = #GtkStack( + %set install-label = #child/GtkLabel(""() + label = "Install"; + ); + %set cancel-label = #child/GtkLabel(""() + label = "Cancel"; + ); + ); set btn = #child/("" ("pill" "install-button") - use-underline = true; + child = stack; ); allocate btn %width%, %height%, #(); @@ -42,7 +54,7 @@ defwidget "Install Button" { } state-default "inactive" { - set btn:label = "_Install"; + set stack:visible-child = install-label; set x = #eval((#(%width%)-#(w))/2.0); set w = #eval(#(b)*2.0); @@ -56,7 +68,7 @@ defwidget "Install Button" { } state "pending" { - set btn:label = "_Cancel"; + set stack:visible-child = cancel-label; set x = #eval((0.5+0.5*sin(3.0*#(t:time))) * (#(%width%)-#(w))); set w = #eval(#(%width%)*0.8); @@ -70,7 +82,7 @@ defwidget "Install Button" { } state "fraction" { - set btn:label = "_Cancel"; + set stack:visible-child = cancel-label; set x = 0.0; set w = #eval(#(%height%)+(#(%width%)-#(%height%))*#(progress)); From 6d87af2e8bc0f1e66d5fe718ca28ec85167e17aa Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Mon, 13 Apr 2026 11:11:56 +0200 Subject: [PATCH 03/16] Try to improve styling --- src/bz-install-controls.c | 2 +- src/bz-install-controls.wdgt | 33 +++++++++++++++------------------ src/style.css | 8 ++++++++ 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index 8cffd1cb..4ba7a8d0 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -354,7 +354,7 @@ bz_install_controls_init (BzInstallControls *self) gtk_widget_init_template (GTK_WIDGET (self)); btn = bge_wdgt_renderer_lookup_object ( - BGE_WDGT_RENDERER (self->install_button), "btn"); + BGE_WDGT_RENDERER (self->install_button), "btn-install"); g_signal_connect_swapped ( btn, "clicked", G_CALLBACK (install_cb), self); diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index cc62f7ed..be76cf3b 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -3,12 +3,11 @@ defwidget "Install Button" { var progress : "gdouble"; var t : "BgeWdgtTime"; - var btn : "GtkButton"; + var btn-install : "GtkButton"; + var btn-cancel : "GtkButton"; var bg : "GtkFixed"; var stack : "GtkStack"; - var install-label : "GtkLabel"; - var cancel-label : "GtkLabel"; var x : "gdouble"; var w : "gdouble"; @@ -23,22 +22,20 @@ defwidget "Install Button" { init { set progress = #transition(state:transaction-manager:current-progress, 1.1, 0.1, 10.0); set t = #(notify-msec = 10;); - - set stack = #GtkStack( - %set install-label = #child/GtkLabel(""() + set stack = #child/GtkStack(""() + transition-type = #GtkStackTransitionType(crossfade); + transition-duration = 200; + %set btn-install = #child/GtkButton(""("pill" "suggested-action") label = "Install"; ); - %set cancel-label = #child/GtkLabel(""() + %set btn-cancel = #child/GtkButton(""("pill" "install-button") label = "Cancel"; ); ); - set btn = #child/("" ("pill" "install-button") - child = stack; - ); - allocate btn %width%, %height%, #(); - + allocate stack %width%, %height%, #(); set bg = #child/("" ("install-button" "install-button-indicator") opacity = opacity; + can-target = false; ); set final-w = #eval(#(w)-2.0*#(b)); @@ -46,16 +43,16 @@ defwidget "Install Button" { set final-x = #eval(#(x)+#(b)); set final-y = b; allocate bg final-w, final-h, #(translate(#GraphenePoint(final-x, final-y));); - + snapshot { do-child bg; - do-child btn; + do-child stack; } } state-default "inactive" { - set stack:visible-child = install-label; - + set stack:visible-child = btn-install; + set x = #eval((#(%width%)-#(w))/2.0); set w = #eval(#(b)*2.0); set b = #eval(#(%height%)/3.0); @@ -68,7 +65,7 @@ defwidget "Install Button" { } state "pending" { - set stack:visible-child = cancel-label; + set stack:visible-child = btn-cancel; set x = #eval((0.5+0.5*sin(3.0*#(t:time))) * (#(%width%)-#(w))); set w = #eval(#(%width%)*0.8); @@ -82,7 +79,7 @@ defwidget "Install Button" { } state "fraction" { - set stack:visible-child = cancel-label; + set stack:visible-child = btn-cancel; set x = 0.0; set w = #eval(#(%height%)+(#(%width%)-#(%height%))*#(progress)); diff --git a/src/style.css b/src/style.css index 86df7c63..962a3473 100644 --- a/src/style.css +++ b/src/style.css @@ -902,6 +902,14 @@ curated-list-view list { color: var(--accent-color); } +.install-button:hover { + background-color: alpha(var(--accent-bg-color), 0.5); +} + +.install-button:active { + background-color: alpha(var(--accent-bg-color), 0.666); +} + .install-button-indicator { border-radius: 9999px; } From 55c261b6747ef7c77644795945b8c730f567552e Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:07:18 +0200 Subject: [PATCH 04/16] Make cancel button work --- src/bz-install-controls.c | 24 +++++++++++++-- src/bz-install-controls.wdgt | 2 +- src/bz-transaction-entry-tracker.txt | 2 +- src/bz-transaction-manager.c | 7 +++++ src/bz-transaction-manager.h | 3 ++ src/bz-transaction-tile.blp | 24 +++++++++++++++ src/bz-transaction-tile.c | 23 +++++++------- src/bz-transaction.c | 2 ++ src/bz-window.c | 46 ++++++++++++++++++++++++++++ 9 files changed, 116 insertions(+), 17 deletions(-) diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index 4ba7a8d0..bc1831d2 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -61,6 +61,17 @@ enum }; static guint signals[LAST_SIGNAL]; +static void +cancel_cb (BzInstallControls *self, + GtkButton *button) +{ + if (self->group == NULL) + return; + + gtk_widget_activate_action (GTK_WIDGET (self), "window.cancel-group", "s", + bz_entry_group_get_id (self->group)); +} + static void install_cb (BzInstallControls *self, GtkButton *button) @@ -347,17 +358,24 @@ bz_install_controls_class_init (BzInstallControlsClass *klass) static void bz_install_controls_init (BzInstallControls *self) { - g_autoptr (GtkWidget) btn = NULL; + g_autoptr (GtkWidget) btn_install = NULL; + g_autoptr (GtkWidget) btn_cancel = NULL; self->wide = TRUE; gtk_widget_init_template (GTK_WIDGET (self)); - btn = bge_wdgt_renderer_lookup_object ( + btn_install = bge_wdgt_renderer_lookup_object ( BGE_WDGT_RENDERER (self->install_button), "btn-install"); g_signal_connect_swapped ( - btn, "clicked", + btn_install, "clicked", G_CALLBACK (install_cb), self); + + btn_cancel = bge_wdgt_renderer_lookup_object ( + BGE_WDGT_RENDERER (self->install_button), "btn-cancel"); + g_signal_connect_swapped ( + btn_cancel, "clicked", + G_CALLBACK (cancel_cb), self); } GtkWidget * diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index be76cf3b..daae62ff 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -23,7 +23,7 @@ defwidget "Install Button" { set progress = #transition(state:transaction-manager:current-progress, 1.1, 0.1, 10.0); set t = #(notify-msec = 10;); set stack = #child/GtkStack(""() - transition-type = #GtkStackTransitionType(crossfade); + transition-type = crossfade; transition-duration = 200; %set btn-install = #child/GtkButton(""("pill" "suggested-action") label = "Install"; diff --git a/src/bz-transaction-entry-tracker.txt b/src/bz-transaction-entry-tracker.txt index 66c4e29e..df5f8518 100644 --- a/src/bz-transaction-entry-tracker.txt +++ b/src/bz-transaction-entry-tracker.txt @@ -5,7 +5,7 @@ parent-name=object author=AUTOGEN enum=bz transaction_entry_kind install update removal -enum=bz transaction_entry_status queued ongoing done +enum=bz transaction_entry_status queued ongoing done cancelled include= include="bz-entry.h" diff --git a/src/bz-transaction-manager.c b/src/bz-transaction-manager.c index 1e5b24a8..a3e5fa04 100644 --- a/src/bz-transaction-manager.c +++ b/src/bz-transaction-manager.c @@ -493,6 +493,13 @@ bz_transaction_manager_get_has_transactions (BzTransactionManager *self) return g_list_model_get_n_items (G_LIST_MODEL (self->transactions)) > 0; } +GListModel * +bz_transaction_manager_get_all_trackers (BzTransactionManager *self) +{ + g_return_val_if_fail (BZ_IS_TRANSACTION_MANAGER (self), NULL); + return G_LIST_MODEL (self->all_trackers); +} + DexFuture * bz_transaction_manager_add (BzTransactionManager *self, BzTransaction *transaction) diff --git a/src/bz-transaction-manager.h b/src/bz-transaction-manager.h index 7027d6cf..638209ff 100644 --- a/src/bz-transaction-manager.h +++ b/src/bz-transaction-manager.h @@ -70,6 +70,9 @@ bz_transaction_manager_get_pending (BzTransactionManager *self); gboolean bz_transaction_manager_get_has_transactions (BzTransactionManager *self); +GListModel * +bz_transaction_manager_get_all_trackers (BzTransactionManager *self); + G_GNUC_WARN_UNUSED_RESULT DexFuture * bz_transaction_manager_add (BzTransactionManager *self, diff --git a/src/bz-transaction-tile.blp b/src/bz-transaction-tile.blp index 992b7204..85f7314a 100644 --- a/src/bz-transaction-tile.blp +++ b/src/bz-transaction-tile.blp @@ -207,6 +207,30 @@ template $BzTransactionTile: $BzListTile { } } + Box { + visible: bind $is_cancelled(template.tracker as <$BzTransactionEntryTracker>.status as <$BzTransactionEntryStatus>) as ; + halign: start; + spacing: 4; + margin-top: 8; + + styles [ + "grey", + "colored", + "small-pill", + "download-size-pill", + ] + + Label { + styles [ + "caption-heading", + ] + + valign: center; + xalign: 0.0; + label: _("Cancelled"); + } + } + Box { visible: bind $is_transaction_tracker_errored(template.tracker as <$BzTransactionEntryTracker>.finished-ops) as ; halign: start; diff --git a/src/bz-transaction-tile.c b/src/bz-transaction-tile.c index c5a15ec4..d6497565 100644 --- a/src/bz-transaction-tile.c +++ b/src/bz-transaction-tile.c @@ -211,6 +211,13 @@ is_completed (gpointer object, return status == BZ_TRANSACTION_ENTRY_STATUS_DONE; } +static gboolean +is_cancelled (gpointer object, + BzTransactionEntryStatus status) +{ + return status == BZ_TRANSACTION_ENTRY_STATUS_CANCELLED; +} + static gboolean is_both (gpointer object, gboolean first, @@ -309,28 +316,19 @@ static void cancel_cb (BzTransactionTile *self, GtkButton *button) { - gboolean result = FALSE; BzTransactionEntryTracker *tracker = NULL; BzEntry *entry = NULL; - BzStateInfo *state = NULL; - BzBackend *backend = NULL; tracker = bz_transaction_tile_get_tracker (self); if (tracker == NULL) return; entry = bz_transaction_entry_tracker_get_entry (tracker); - if (entry == NULL || !BZ_IS_FLATPAK_ENTRY (entry)) - return; - - state = bz_state_info_get_default (); - backend = bz_state_info_get_backend (state); - if (backend == NULL) + if (entry == NULL) return; - result = bz_backend_cancel_task_for_entry (backend, entry); - if (result) - gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE); + gtk_widget_activate_action (GTK_WIDGET (self), "window.cancel-group", "s", + bz_entry_get_id (entry)); } static void @@ -405,6 +403,7 @@ bz_transaction_tile_class_init (BzTransactionTileClass *klass) gtk_widget_class_bind_template_callback (widget_class, is_queued); gtk_widget_class_bind_template_callback (widget_class, is_ongoing); gtk_widget_class_bind_template_callback (widget_class, is_completed); + gtk_widget_class_bind_template_callback (widget_class, is_cancelled); gtk_widget_class_bind_template_callback (widget_class, is_both); gtk_widget_class_bind_template_callback (widget_class, run_cb); gtk_widget_class_bind_template_callback (widget_class, cancel_cb); diff --git a/src/bz-transaction.c b/src/bz-transaction.c index e498a32f..dd7598af 100644 --- a/src/bz-transaction.c +++ b/src/bz-transaction.c @@ -689,6 +689,8 @@ finish (BzTransactionPrivate *priv) g_autoptr (BzTransactionEntryTracker) tracker = NULL; tracker = g_list_model_get_item (G_LIST_MODEL (priv->trackers), i); + if (bz_transaction_entry_tracker_get_status (tracker) == BZ_TRANSACTION_ENTRY_STATUS_CANCELLED) + continue; bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_DONE); } } diff --git a/src/bz-window.c b/src/bz-window.c index bc2ace68..571e73ef 100644 --- a/src/bz-window.c +++ b/src/bz-window.c @@ -422,6 +422,51 @@ action_remove_group (GtkWidget *widget, try_transact (self, NULL, group, TRUE, auto_confirm, NULL); } +static void +action_cancel_group (GtkWidget *widget, + const char *action_name, + GVariant *parameter) +{ + BzWindow *self = BZ_WINDOW (widget); + const char *id = NULL; + BzTransactionManager *manager = NULL; + BzBackend *backend = NULL; + GListModel *trackers = NULL; + guint n_items = 0; + + id = g_variant_get_string (parameter, NULL); + manager = bz_state_info_get_transaction_manager (self->state); + if (manager == NULL) + return; + + backend = bz_state_info_get_backend (self->state); + if (backend == NULL) + return; + + trackers = bz_transaction_manager_get_all_trackers (manager); + n_items = g_list_model_get_n_items (trackers); + + for (guint i = 0; i < n_items; i++) + { + g_autoptr (BzTransactionEntryTracker) tracker = NULL; + BzEntry *entry = NULL; + const char *entry_id = NULL; + + tracker = g_list_model_get_item (trackers, i); + entry = bz_transaction_entry_tracker_get_entry (tracker); + if (entry == NULL) + continue; + + entry_id = bz_entry_get_id (entry); + if (g_strcmp0 (entry_id, id) == 0) + { + if (bz_backend_cancel_task_for_entry (backend, entry)) + g_object_set (tracker, "status", BZ_TRANSACTION_ENTRY_STATUS_CANCELLED, NULL); + break; + } + } +} + static void action_show_group (GtkWidget *widget, const char *action_name, @@ -655,6 +700,7 @@ bz_window_class_init (BzWindowClass *klass) gtk_widget_class_install_action (widget_class, "window.install-group", "(sb)", action_install_group); gtk_widget_class_install_action (widget_class, "window.remove-group", "(sb)", action_remove_group); + gtk_widget_class_install_action (widget_class, "window.cancel-group", "s", action_cancel_group); gtk_widget_class_install_action (widget_class, "window.show-group", "s", action_show_group); gtk_widget_class_install_action (widget_class, "window.addons-group", "s", action_addons_group); gtk_widget_class_install_action (widget_class, "window.bulk-install", NULL, action_bulk_install); From ca3627613748f46025a64bcea960f7e3d9d0a11e Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:15:42 +0200 Subject: [PATCH 05/16] Fix outline --- src/bz-install-controls.blp | 2 ++ src/bz-install-controls.wdgt | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/bz-install-controls.blp b/src/bz-install-controls.blp index d36f15b6..b6ee0f18 100644 --- a/src/bz-install-controls.blp +++ b/src/bz-install-controls.blp @@ -46,6 +46,7 @@ template $BzInstallControls: Box { spacing: bind $choose(template.wide, 10, 8) as ; homogeneous: bind $invert_boolean(template.wide) as ; halign: bind $choose(template.wide, 2, 0) as ; + valign: center; margin-top: 3; margin-bottom: 3; @@ -104,6 +105,7 @@ template $BzInstallControls: Box { spacing: bind $choose(template.wide, 10, 8) as ; homogeneous: bind $invert_boolean(template.wide) as ; halign: bind $choose(template.wide, 2, 0) as ; + valign: center; margin-top: 3; margin-bottom: 3; diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index daae62ff..036c342d 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -27,9 +27,17 @@ defwidget "Install Button" { transition-duration = 200; %set btn-install = #child/GtkButton(""("pill" "suggested-action") label = "Install"; + margin-top = 4; + margin-bottom = 4; + margin-start = 4; + margin-end = 4; ); %set btn-cancel = #child/GtkButton(""("pill" "install-button") label = "Cancel"; + margin-top = 4; + margin-bottom = 4; + margin-start = 4; + margin-end = 4; ); ); allocate stack %width%, %height%, #(); From 1c72579b856ba58a1aa21679e95beb90a36634e2 Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Mon, 13 Apr 2026 14:07:15 +0200 Subject: [PATCH 06/16] Fix focus --- src/bz-install-controls.blp | 7 +------ src/bz-install-controls.c | 12 ++++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/bz-install-controls.blp b/src/bz-install-controls.blp index b6ee0f18..685aae0b 100644 --- a/src/bz-install-controls.blp +++ b/src/bz-install-controls.blp @@ -14,7 +14,7 @@ template $BzInstallControls: Box { StackPage install { name: "install"; - child: $BgeWdgtRenderer install_button { + child: $BgeWdgtRenderer animated_button { margin-top: 3; margin-bottom: 3; margin-start: 3; @@ -31,11 +31,6 @@ template $BzInstallControls: Box { has-tooltip: true; hexpand: bind $invert_boolean(template.wide) as ; halign: bind $choose(template.wide, 2, 0) as ; - // sensitive: bind $invert_boolean($is_zero(template.entry-group as <$BzEntryGroup>.installable-and-available) as ) as ; - - // label: _("_Install"); - // use-underline: true; - // clicked => $install_cb(template); }; } diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index bc1831d2..79dcc779 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -39,6 +39,7 @@ struct _BzInstallControls /* Template widgets */ GtkWidget *open_button; + GtkWidget *animated_button; GtkWidget *install_button; }; @@ -344,7 +345,7 @@ bz_install_controls_class_init (BzInstallControlsClass *klass) bz_widget_class_bind_all_util_callbacks (widget_class); gtk_widget_class_bind_template_child (widget_class, BzInstallControls, open_button); - gtk_widget_class_bind_template_child (widget_class, BzInstallControls, install_button); + gtk_widget_class_bind_template_child (widget_class, BzInstallControls, animated_button); gtk_widget_class_bind_template_callback (widget_class, install_cb); gtk_widget_class_bind_template_callback (widget_class, remove_cb); @@ -358,21 +359,20 @@ bz_install_controls_class_init (BzInstallControlsClass *klass) static void bz_install_controls_init (BzInstallControls *self) { - g_autoptr (GtkWidget) btn_install = NULL; g_autoptr (GtkWidget) btn_cancel = NULL; self->wide = TRUE; gtk_widget_init_template (GTK_WIDGET (self)); - btn_install = bge_wdgt_renderer_lookup_object ( - BGE_WDGT_RENDERER (self->install_button), "btn-install"); + self->install_button = bge_wdgt_renderer_lookup_object ( + BGE_WDGT_RENDERER (self->animated_button), "btn-install"); g_signal_connect_swapped ( - btn_install, "clicked", + self->install_button, "clicked", G_CALLBACK (install_cb), self); btn_cancel = bge_wdgt_renderer_lookup_object ( - BGE_WDGT_RENDERER (self->install_button), "btn-cancel"); + BGE_WDGT_RENDERER (self->animated_button), "btn-cancel"); g_signal_connect_swapped ( btn_cancel, "clicked", G_CALLBACK (cancel_cb), self); From 04fdaf42638ecb9524220adbfb0f70c45f85c1eb Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Tue, 14 Apr 2026 13:30:01 +0200 Subject: [PATCH 07/16] Minor fixes --- src/bz-install-controls.blp | 3 +-- src/bz-install-controls.c | 6 +++++- src/bz-install-controls.wdgt | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/bz-install-controls.blp b/src/bz-install-controls.blp index 685aae0b..3a2ac893 100644 --- a/src/bz-install-controls.blp +++ b/src/bz-install-controls.blp @@ -6,9 +6,8 @@ template $BzInstallControls: Box { Stack { transition-type: crossfade; - visible-child-name: bind $get_visible_page(template.entry-group as <$BzEntryGroup>.installable, template.entry-group as <$BzEntryGroup>.removable, template.state as <$BzStateInfo>.available-updates) as ; + visible-child-name: bind $get_visible_page(template.entry-group as <$BzEntryGroup>.installable, template.entry-group as <$BzEntryGroup>.removable, template.state as <$BzStateInfo>.available-updates, template.state as <$BzStateInfo>.transaction-manager as <$BzTransactionManager>.active as ) as ; hexpand: bind $invert_boolean(template.wide) as ; - hhomogeneous: false; valign: center; StackPage install { diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index 79dcc779..0d4d63c0 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -160,11 +160,15 @@ static char * get_visible_page (gpointer object, int installable, int removable, - GListModel *available_updates) + GListModel *available_updates, + gboolean active) { BzInstallControls *self = BZ_INSTALL_CONTROLS (object); g_autoptr (GListStore) store = NULL; + if (active) + return g_strdup ("install"); + if (removable > 0) { store = find_matching_updates (self, available_updates); diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index 036c342d..98daa101 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -77,7 +77,7 @@ defwidget "Install Button" { set x = #eval((0.5+0.5*sin(3.0*#(t:time))) * (#(%width%)-#(w))); set w = #eval(#(%width%)*0.8); - set b = #eval(#(%height%)*0.2); + set b = #eval(#(%height%)*0.175); set opacity = 1.0; transition-spring x 1.0, 0.1, 50.0; From 42a540986aed220bec7043912bdad8d787338bbb Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:17:14 +0200 Subject: [PATCH 08/16] Switch to local tracker --- src/bz-install-controls.blp | 16 +++-- src/bz-install-controls.c | 101 +++++++++++++++++++++++++-- src/bz-install-controls.wdgt | 4 +- src/bz-transaction-entry-tracker.txt | 3 + src/bz-transaction-manager.c | 11 +++ src/bz-transaction.c | 45 +++++++++--- 6 files changed, 154 insertions(+), 26 deletions(-) diff --git a/src/bz-install-controls.blp b/src/bz-install-controls.blp index 3a2ac893..678228c1 100644 --- a/src/bz-install-controls.blp +++ b/src/bz-install-controls.blp @@ -6,7 +6,10 @@ template $BzInstallControls: Box { Stack { transition-type: crossfade; - visible-child-name: bind $get_visible_page(template.entry-group as <$BzEntryGroup>.installable, template.entry-group as <$BzEntryGroup>.removable, template.state as <$BzStateInfo>.available-updates, template.state as <$BzStateInfo>.transaction-manager as <$BzTransactionManager>.active as ) as ; + visible-child-name: bind try { + $get_visible_page(template.entry-group as <$BzEntryGroup>.installable, template.entry-group as <$BzEntryGroup>.removable, template.state as <$BzStateInfo>.available-updates, template.tracker as <$BzTransactionEntryTracker>.active as ) as , + $get_visible_page(template.entry-group as <$BzEntryGroup>.installable, template.entry-group as <$BzEntryGroup>.removable, template.state as <$BzStateInfo>.available-updates, false ) as + }; hexpand: bind $invert_boolean(template.wide) as ; valign: center; @@ -20,12 +23,13 @@ template $BzInstallControls: Box { margin-end: 3; resource: "/io/github/kolunmi/Bazaar/bz-install-controls.wdgt"; - reference: bind template.state as <$BzStateInfo>; + reference: bind template.tracker as <$BzTransactionEntryTracker>; - state: bind $get_install_btn_state( - template.state as <$BzStateInfo>.transaction-manager as <$BzTransactionManager>.active as , - template.state as <$BzStateInfo>.transaction-manager as <$BzTransactionManager>.pending as - ) as ; + state: bind try { $get_install_btn_state( + template.tracker as <$BzTransactionEntryTracker>.active as , + template.tracker as <$BzTransactionEntryTracker>.pending as , + template.tracker as <$BzTransactionEntryTracker>.progress as + ) as , "inactive"}; has-tooltip: true; hexpand: bind $invert_boolean(template.wide) as ; diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index 0d4d63c0..ab85ddf5 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -33,9 +33,10 @@ struct _BzInstallControls { GtkBox parent_instance; - BzEntryGroup *group; - BzStateInfo *state; - gboolean wide; + BzEntryGroup *group; + BzStateInfo *state; + gboolean wide; + BzTransactionEntryTracker *tracker; /* Template widgets */ GtkWidget *open_button; @@ -51,6 +52,7 @@ enum PROP_WIDE, PROP_ENTRY_GROUP, PROP_STATE, + PROP_TRACKER, LAST_PROP }; static GParamSpec *props[LAST_PROP] = { 0 }; @@ -62,6 +64,53 @@ enum }; static guint signals[LAST_SIGNAL]; +static void +update_tracker (BzInstallControls *self) +{ + BzTransactionManager *manager = NULL; + g_autoptr (GListModel) all = NULL; + const char *group_id = NULL; + g_autoptr (BzTransactionEntryTracker) found = NULL; + + if (self->state != NULL) + manager = bz_state_info_get_transaction_manager (self->state); + if (manager != NULL) + g_object_get (manager, "all-trackers", &all, NULL); + if (self->group != NULL) + group_id = bz_entry_group_get_id (self->group); + + if (all != NULL && group_id != NULL) + { + for (guint i = 0; i < g_list_model_get_n_items (all); i++) + { + g_autoptr (BzTransactionEntryTracker) tracker = NULL; + BzEntry *entry = NULL; + + tracker = g_list_model_get_item (all, i); + entry = bz_transaction_entry_tracker_get_entry (tracker); + + if (g_strcmp0 (entry != NULL ? bz_entry_get_id (entry) : NULL, group_id) == 0) + { + found = g_steal_pointer (&tracker); + break; + } + } + } + + if (g_set_object (&self->tracker, found)) + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TRACKER]); +} + +static void +on_all_trackers_changed (GListModel *model, + guint position, + guint removed, + guint added, + BzInstallControls *self) +{ + update_tracker (self); +} + static void cancel_cb (BzInstallControls *self, GtkButton *button) @@ -183,7 +232,8 @@ get_visible_page (gpointer object, static char * get_install_btn_state (gpointer object, gboolean active, - gboolean pending) + gboolean pending, + double progress) { if (pending) return g_strdup ("pending"); @@ -242,6 +292,7 @@ bz_install_controls_dispose (GObject *object) g_clear_object (&self->group); g_clear_object (&self->state); + g_clear_object (&self->tracker); G_OBJECT_CLASS (bz_install_controls_parent_class)->dispose (object); } @@ -265,6 +316,9 @@ bz_install_controls_get_property (GObject *object, case PROP_STATE: g_value_set_object (value, self->state); break; + case PROP_TRACKER: + g_value_set_object (value, self->tracker); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -325,6 +379,13 @@ bz_install_controls_class_init (BzInstallControlsClass *klass) BZ_TYPE_STATE_INFO, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + props[PROP_TRACKER] = + g_param_spec_object ( + "tracker", + NULL, NULL, + BZ_TYPE_TRANSACTION_ENTRY_TRACKER, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, LAST_PROP, props); signals[SIGNAL_UPDATE] = @@ -363,7 +424,7 @@ bz_install_controls_class_init (BzInstallControlsClass *klass) static void bz_install_controls_init (BzInstallControls *self) { - g_autoptr (GtkWidget) btn_cancel = NULL; + g_autoptr (GtkWidget) btn_cancel = NULL; self->wide = TRUE; @@ -436,6 +497,8 @@ bz_install_controls_set_entry_group (BzInstallControls *self, G_PRIORITY_DEFAULT_IDLE, (GSourceFunc) idle_grab_focus, bz_track_weak (self), bz_weak_release); + + update_tracker (self); } BzStateInfo * @@ -451,9 +514,33 @@ bz_install_controls_set_state (BzInstallControls *self, { g_return_if_fail (BZ_IS_INSTALL_CONTROLS (self)); - g_clear_object (&self->state); + if (self->state != NULL) + { + BzTransactionManager *old_mgr = NULL; + g_autoptr (GListModel) all = NULL; + + old_mgr = bz_state_info_get_transaction_manager (self->state); + if (old_mgr != NULL) + g_object_get (old_mgr, "all-trackers", &all, NULL); + if (all != NULL) + g_signal_handlers_disconnect_by_func (all, on_all_trackers_changed, self); + } + + g_set_object (&self->state, state); + if (state != NULL) - self->state = g_object_ref (state); + { + BzTransactionManager *mgr = NULL; + g_autoptr (GListModel) all = NULL; + + mgr = bz_state_info_get_transaction_manager (state); + if (mgr != NULL) + g_object_get (mgr, "all-trackers", &all, NULL); + if (all != NULL) + g_signal_connect (all, "items-changed", + G_CALLBACK (on_all_trackers_changed), self); + } g_object_notify_by_pspec (G_OBJECT (self), props[PROP_STATE]); + update_tracker (self); } diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index 98daa101..f37e7c1d 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -1,5 +1,5 @@ defwidget "Install Button" { - reference state : "BzStateInfo"; + reference state : "BzTransactionEntryTracker"; var progress : "gdouble"; var t : "BgeWdgtTime"; @@ -20,7 +20,7 @@ defwidget "Install Button" { var final-h : "gdouble"; init { - set progress = #transition(state:transaction-manager:current-progress, 1.1, 0.1, 10.0); + set progress = #transition(state:progress, 1.1, 0.1, 10.0); set t = #(notify-msec = 10;); set stack = #child/GtkStack(""() transition-type = crossfade; diff --git a/src/bz-transaction-entry-tracker.txt b/src/bz-transaction-entry-tracker.txt index df5f8518..578c6b6d 100644 --- a/src/bz-transaction-entry-tracker.txt +++ b/src/bz-transaction-entry-tracker.txt @@ -15,3 +15,6 @@ property=current_ops GListModel G_TYPE_LIST_MODEL object property=finished_ops GListModel G_TYPE_LIST_MODEL object property=kind BzTransactionEntryKind BZ_TYPE_TRANSACTION_ENTRY_KIND enum property=status BzTransactionEntryStatus BZ_TYPE_TRANSACTION_ENTRY_STATUS enum +property=progress double G_TYPE_DOUBLE double +property=pending gboolean G_TYPE_BOOLEAN boolean +property=active gboolean G_TYPE_BOOLEAN boolean diff --git a/src/bz-transaction-manager.c b/src/bz-transaction-manager.c index a3e5fa04..8d90dd53 100644 --- a/src/bz-transaction-manager.c +++ b/src/bz-transaction-manager.c @@ -95,6 +95,7 @@ enum PROP_CURRENT_PROGRESS, PROP_INSTALL_TRACKERS, PROP_REMOVAL_TRACKERS, + PROP_ALL_TRACKERS, LAST_PROP }; @@ -178,6 +179,9 @@ bz_transaction_manager_get_property (GObject *object, case PROP_REMOVAL_TRACKERS: g_value_set_object (value, self->removal_trackers); break; + case PROP_ALL_TRACKERS: + g_value_set_object (value, self->all_trackers); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -335,6 +339,13 @@ bz_transaction_manager_class_init (BzTransactionManagerClass *klass) G_TYPE_LIST_MODEL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + props[PROP_ALL_TRACKERS] = + g_param_spec_object ( + "all-trackers", + NULL, NULL, + G_TYPE_LIST_MODEL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, LAST_PROP, props); signals[SIGNAL_SUCCESS] = diff --git a/src/bz-transaction.c b/src/bz-transaction.c index dd7598af..c9439dcd 100644 --- a/src/bz-transaction.c +++ b/src/bz-transaction.c @@ -89,9 +89,11 @@ find_and_maybe_transfer (GListStore *from, gpointer *out); static void -tracker_update (BzTransactionPrivate *priv, - BzBackendTransactionOpPayload *payload, - gboolean transfer); +tracker_update (BzTransactionPrivate *priv, + BzBackendTransactionOpPayload *payload, + BzBackendTransactionOpProgressPayload *progress_payload, + gboolean transfer, + gboolean set_done); static void bz_transaction_dispose (GObject *object) @@ -388,6 +390,9 @@ bz_transaction_new_full (BzEntry **installs, bz_transaction_entry_tracker_set_finished_ops (tracker, G_LIST_MODEL (finished_ops)); \ bz_transaction_entry_tracker_set_kind (tracker, transaction_type); \ bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_QUEUED); \ + bz_transaction_entry_tracker_set_pending (tracker, TRUE); \ + if ((transaction_type) == BZ_TRANSACTION_ENTRY_KIND_REMOVAL) \ + bz_transaction_entry_tracker_set_active (tracker, TRUE); \ \ g_list_store_append (priv->trackers, tracker); \ } \ @@ -627,7 +632,7 @@ bz_transaction_update_task (BzTransaction *self, if (result) bz_transaction_task_set_last_progress (task, payload); - tracker_update (priv, op, FALSE); + tracker_update (priv, op, payload, FALSE, FALSE); } void @@ -648,7 +653,7 @@ bz_transaction_finish_task (BzTransaction *self, (GEqualFuncFull) find_payload_eq_func, NULL); - tracker_update (priv, payload, TRUE); + tracker_update (priv, payload, NULL, TRUE, FALSE); } void @@ -675,7 +680,7 @@ bz_transaction_error_out_task (BzTransaction *self, if (result) bz_transaction_task_set_error (task, message); - tracker_update (priv, payload, TRUE); + tracker_update (priv, payload, NULL, TRUE, TRUE); } static void @@ -689,6 +694,8 @@ finish (BzTransactionPrivate *priv) g_autoptr (BzTransactionEntryTracker) tracker = NULL; tracker = g_list_model_get_item (G_LIST_MODEL (priv->trackers), i); + bz_transaction_entry_tracker_set_active (tracker, FALSE); + bz_transaction_entry_tracker_set_pending (tracker, FALSE); if (bz_transaction_entry_tracker_get_status (tracker) == BZ_TRANSACTION_ENTRY_STATUS_CANCELLED) continue; bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_DONE); @@ -744,9 +751,11 @@ find_and_maybe_transfer (GListStore *from, } static void -tracker_update (BzTransactionPrivate *priv, - BzBackendTransactionOpPayload *payload, - gboolean transfer) +tracker_update (BzTransactionPrivate *priv, + BzBackendTransactionOpPayload *payload, + BzBackendTransactionOpProgressPayload *progress_payload, + gboolean transfer, + gboolean set_done) { BzEntry *entry = NULL; g_autoptr (BzTransactionEntryTracker) tracker = NULL; @@ -767,7 +776,11 @@ tracker_update (BzTransactionPrivate *priv, GListModel *from = NULL; GListModel *to = NULL; - bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_DONE); + if (set_done) { + bz_transaction_entry_tracker_set_active (tracker, FALSE); + bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_DONE); + bz_transaction_entry_tracker_set_pending (tracker, FALSE); + } from = bz_transaction_entry_tracker_get_current_ops (tracker); to = bz_transaction_entry_tracker_get_finished_ops (tracker); @@ -782,6 +795,16 @@ tracker_update (BzTransactionPrivate *priv, g_object_notify (G_OBJECT (tracker), "finished-ops"); } else - bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_ONGOING); + { + if (progress_payload != NULL) + { + g_object_set (tracker, + "progress", bz_backend_transaction_op_progress_payload_get_total_progress (progress_payload), + "pending", bz_backend_transaction_op_progress_payload_get_is_estimating (progress_payload), + NULL); + } + bz_transaction_entry_tracker_set_active (tracker, TRUE); + bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_ONGOING); + } } } From 2cf464ba89ba3c1f20345703ca5ad4833a922ecc Mon Sep 17 00:00:00 2001 From: Eva M Date: Wed, 15 Apr 2026 20:14:32 -0700 Subject: [PATCH 09/16] eliminate usage of BgeWdgtTime for `%tick%` builtin --- src/bz-install-controls.wdgt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index f37e7c1d..652b72c8 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -2,7 +2,6 @@ defwidget "Install Button" { reference state : "BzTransactionEntryTracker"; var progress : "gdouble"; - var t : "BgeWdgtTime"; var btn-install : "GtkButton"; var btn-cancel : "GtkButton"; var bg : "GtkFixed"; @@ -21,7 +20,6 @@ defwidget "Install Button" { init { set progress = #transition(state:progress, 1.1, 0.1, 10.0); - set t = #(notify-msec = 10;); set stack = #child/GtkStack(""() transition-type = crossfade; transition-duration = 200; @@ -75,7 +73,7 @@ defwidget "Install Button" { state "pending" { set stack:visible-child = btn-cancel; - set x = #eval((0.5+0.5*sin(3.0*#(t:time))) * (#(%width%)-#(w))); + set x = #eval((0.5+0.5*sin(3.0*#(%tick%))) * (#(%width%)-#(w))); set w = #eval(#(%width%)*0.8); set b = #eval(#(%height%)*0.175); set opacity = 1.0; From 3b004d50a6eea74292187e20145cba124825bafa Mon Sep 17 00:00:00 2001 From: Eva M Date: Wed, 15 Apr 2026 20:15:50 -0700 Subject: [PATCH 10/16] fix indentation --- src/bz-install-controls.wdgt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index 652b72c8..44b4f6fd 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -27,15 +27,15 @@ defwidget "Install Button" { label = "Install"; margin-top = 4; margin-bottom = 4; - margin-start = 4; - margin-end = 4; + margin-start = 4; + margin-end = 4; ); %set btn-cancel = #child/GtkButton(""("pill" "install-button") label = "Cancel"; margin-top = 4; margin-bottom = 4; - margin-start = 4; - margin-end = 4; + margin-start = 4; + margin-end = 4; ); ); allocate stack %width%, %height%, #(); From 26236b86cb8f58c54061a2d05c95b75f5f3f6900 Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Sat, 18 Apr 2026 20:54:20 +0200 Subject: [PATCH 11/16] Use install controls in addon dialog --- src/bz-addons-dialog.blp | 51 +++------------------------- src/bz-addons-dialog.c | 71 +++++++++------------------------------ src/bz-install-controls.c | 3 +- src/bz-window.c | 47 ++++++++++++++++++-------- 4 files changed, 55 insertions(+), 117 deletions(-) diff --git a/src/bz-addons-dialog.blp b/src/bz-addons-dialog.blp index 4542beae..dabeba60 100644 --- a/src/bz-addons-dialog.blp +++ b/src/bz-addons-dialog.blp @@ -262,56 +262,13 @@ template $BzAddonsDialog: Adw.Dialog { styles ["dimmed"] } - Stack { - transition-type: crossfade; + $BzInstallControls { halign: center; margin-top: 6; margin-bottom: 8; - visible-child-name: bind $get_install_stack_page(template.selected-group as <$BzEntryGroup>.installable, template.selected-group as <$BzEntryGroup>.removable) as ; - - StackPage { - name: "install"; - child: Button { - margin-top: 6; - margin-bottom: 6; - margin-start: 6; - margin-end: 6; - styles ["pill", "suggested-action"] - label: _("Install"); - sensitive: bind $invert_boolean($is_zero(template.selected-group as <$BzEntryGroup>.installable-and-available) as ) as ; - clicked => $install_cb(); - }; - } - - StackPage { - name: "open"; - child: Box { - spacing: 8; - margin-top: 6; - margin-bottom: 6; - margin-start: 6; - margin-end: 6; - - Button { - styles ["pill"] - label: _("Open"); - sensitive: bind $invert_boolean($is_zero(template.selected-group as <$BzEntryGroup>.removable-and-available) as ) as ; - clicked => $run_cb(); - } - - Button { - styles ["pill", "destructive-action"] - label: _("Remove"); - sensitive: bind $invert_boolean($is_zero(template.selected-group as <$BzEntryGroup>.removable-and-available) as ) as ; - clicked => $remove_cb(); - } - }; - } - - StackPage { - name: "empty"; - child: Adw.Bin {}; - } + wide: false; + entry-group: bind template.selected-group; + state: bind template.state; } Label { diff --git a/src/bz-addons-dialog.c b/src/bz-addons-dialog.c index f2c1958f..f7cae773 100644 --- a/src/bz-addons-dialog.c +++ b/src/bz-addons-dialog.c @@ -52,6 +52,7 @@ struct _BzAddonsDialog DexFuture *selected_ui_future; BzResult *parent_ui_entry; DexFuture *parent_ui_future; + BzStateInfo *state; AdwAnimation *width_animation; AdwAnimation *height_animation; @@ -74,6 +75,7 @@ enum PROP_SELECTED_GROUP, PROP_SELECTED_UI_ENTRY, PROP_PARENT_UI_ENTRY, + PROP_STATE, LAST_PROP }; @@ -87,10 +89,6 @@ static void license_cb (BzAddonsDialog *self, GtkButton *button); static void dl_stats_cb (BzAddonsDialog *self, GtkButton *button); static void animate_to_size (BzAddonsDialog *self); static void on_visible_page_tag_changed (AdwNavigationView *nav_view, GParamSpec *pspec, BzAddonsDialog *self); -static char *get_install_stack_page (gpointer object, int installable, int removable); -static void install_cb (GtkButton *button, BzAddonsDialog *self); -static void remove_cb (GtkButton *button, BzAddonsDialog *self); -static void run_cb (GtkButton *button, BzAddonsDialog *self); static DexFuture *on_parent_ui_entry_resolved (DexFuture *future, GWeakRef *wr); static DexFuture *on_selected_ui_entry_resolved (DexFuture *future, GWeakRef *wr); static void set_selected_group (BzAddonsDialog *self, BzEntryGroup *group); @@ -108,6 +106,7 @@ bz_addons_dialog_dispose (GObject *object) g_clear_object (&self->selected_group); g_clear_object (&self->selected_ui_entry); g_clear_object (&self->parent_ui_entry); + g_clear_object (&self->state); g_clear_object (&self->width_animation); g_clear_object (&self->height_animation); @@ -136,6 +135,9 @@ bz_addons_dialog_get_property (GObject *object, case PROP_PARENT_UI_ENTRY: g_value_set_object (value, self->parent_ui_entry); break; + case PROP_STATE: + g_value_set_object (value, bz_state_info_get_default ()); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -204,6 +206,13 @@ bz_addons_dialog_class_init (BzAddonsDialogClass *klass) BZ_TYPE_RESULT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + props[PROP_STATE] = + g_param_spec_object ( + "state", + NULL, NULL, + BZ_TYPE_STATE_INFO, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, LAST_PROP, props); g_type_ensure (BZ_TYPE_ADDON_TILE); @@ -233,10 +242,6 @@ bz_addons_dialog_class_init (BzAddonsDialogClass *klass) gtk_widget_class_bind_template_callback (widget_class, format_parent_title); gtk_widget_class_bind_template_callback (widget_class, get_description_max_height); gtk_widget_class_bind_template_callback (widget_class, get_description_toggle_text); - gtk_widget_class_bind_template_callback (widget_class, get_install_stack_page); - gtk_widget_class_bind_template_callback (widget_class, install_cb); - gtk_widget_class_bind_template_callback (widget_class, remove_cb); - gtk_widget_class_bind_template_callback (widget_class, run_cb); gtk_widget_class_bind_template_callback (widget_class, license_cb); gtk_widget_class_bind_template_callback (widget_class, size_cb); @@ -283,9 +288,9 @@ bz_addons_dialog_new (BzEntryGroup *group) NULL); if (groups == NULL || g_list_model_get_n_items (groups) == 0) - adw_navigation_view_replace (self->navigation_view, - (AdwNavigationPage *[]) { adw_navigation_view_find_page (self->navigation_view, "empty") }, - 1); + adw_navigation_view_replace (self->navigation_view, + (AdwNavigationPage *[]) { adw_navigation_view_find_page (self->navigation_view, "empty") }, + 1); else if (g_list_model_get_n_items (groups) == 1) { g_autoptr (BzEntryGroup) single = g_list_model_get_item (groups, 0); @@ -483,50 +488,6 @@ on_visible_page_tag_changed (AdwNavigationView *nav_view, g_idle_add_once ((GSourceOnceFunc) animate_to_size, self); } -static char * -get_install_stack_page (gpointer object, - int installable, - int removable) -{ - if (removable > 0) - return g_strdup ("open"); - else if (installable > 0) - return g_strdup ("install"); - else - return g_strdup ("empty"); -} - -static void -install_cb (GtkButton *button, - BzAddonsDialog *self) -{ - if (self->selected_group == NULL) - return; - gtk_widget_activate_action (GTK_WIDGET (self), "window.install-group", "(sb)", - bz_entry_group_get_id (self->selected_group), TRUE); -} - -static void -remove_cb (GtkButton *button, - BzAddonsDialog *self) -{ - if (self->selected_group == NULL) - return; - gtk_widget_activate_action (GTK_WIDGET (self), "window.remove-group", "(sb)", - bz_entry_group_get_id (self->selected_group), TRUE); -} - -static void -run_cb (GtkButton *button, - BzAddonsDialog *self) -{ - BzEntry *entry = NULL; - entry = bz_result_get_object (self->parent_ui_entry); - - gtk_widget_activate_action (GTK_WIDGET (self), "window.launch-group", "s", - bz_entry_get_id (entry)); -} - static DexFuture * on_parent_ui_entry_resolved (DexFuture *future, GWeakRef *wr) diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index ab85ddf5..413983f8 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -220,7 +220,8 @@ get_visible_page (gpointer object, if (removable > 0) { - store = find_matching_updates (self, available_updates); + if (g_signal_has_handler_pending (self, signals[SIGNAL_UPDATE], 0, FALSE)) + store = find_matching_updates (self, available_updates); return g_strdup (store != NULL ? "update" : "open"); } else if (installable > 0) diff --git a/src/bz-window.c b/src/bz-window.c index 571e73ef..97d644af 100644 --- a/src/bz-window.c +++ b/src/bz-window.c @@ -572,10 +572,10 @@ action_open_library (GtkWidget *widget, static DexFuture * launch_group_fiber (BzEntryGroup *group) { - g_autoptr (GError) local_error = NULL; - g_autoptr (GListStore) store = NULL; - GtkWidget *window = NULL; - BzStateInfo *state = NULL; + g_autoptr (GError) local_error = NULL; + g_autoptr (GListStore) store = NULL; + GtkWidget *window = NULL; + BzStateInfo *state = NULL; state = bz_state_info_get_default (); window = GTK_WIDGET (gtk_application_get_active_window ( @@ -592,21 +592,40 @@ launch_group_fiber (BzEntryGroup *group) for (guint i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (store)); i++) { - g_autoptr (BzEntry) entry = NULL; + g_autoptr (BzEntry) entry = NULL; + const char *ref = NULL; + gboolean result = FALSE; entry = g_list_model_get_item (G_LIST_MODEL (store), i); - if (BZ_IS_FLATPAK_ENTRY (entry) && bz_entry_is_installed (entry)) - { - gboolean result = bz_flatpak_entry_launch ( - BZ_FLATPAK_ENTRY (entry), - BZ_FLATPAK_INSTANCE (bz_state_info_get_backend (state)), - &local_error); - if (!result && window != NULL) - bz_show_error_for_widget (window, _ ("Failed to launch application"), local_error->message); + if (!BZ_IS_FLATPAK_ENTRY (entry) || !bz_entry_is_installed (entry)) + continue; + + ref = bz_flatpak_entry_get_addon_extension_of_ref (BZ_FLATPAK_ENTRY (entry)); + if (ref != NULL) + { + g_auto (GStrv) parts = NULL; + BzApplicationMapFactory *factory = NULL; + g_autoptr (BzEntryGroup) parent = NULL; - return result ? dex_future_new_true () : dex_future_new_for_error (g_steal_pointer (&local_error)); + parts = g_strsplit (ref, "/", -1); + if (parts[0] != NULL && parts[1] != NULL) + { + factory = bz_state_info_get_application_factory (state); + parent = bz_application_map_factory_convert_one ( + factory, gtk_string_object_new (parts[1])); + if (parent != NULL) + return launch_group_fiber (parent); + } } + + result = bz_flatpak_entry_launch ( + BZ_FLATPAK_ENTRY (entry), + BZ_FLATPAK_INSTANCE (bz_state_info_get_backend (state)), + &local_error); + if (!result && window != NULL) + bz_show_error_for_widget (window, _ ("Failed to launch application"), local_error->message); + return result ? dex_future_new_true () : dex_future_new_for_error (g_steal_pointer (&local_error)); } return dex_future_new_false (); From 4f8b85763158020231ce28026c9bbbc0e6a7fcb6 Mon Sep 17 00:00:00 2001 From: Alexander Vanhee <160625516+AlexanderVanhee@users.noreply.github.com> Date: Sat, 18 Apr 2026 21:46:04 +0200 Subject: [PATCH 12/16] Scale displayed progress to avoid awkward button style --- src/bz-transaction.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/bz-transaction.c b/src/bz-transaction.c index c9439dcd..ae2bdcb5 100644 --- a/src/bz-transaction.c +++ b/src/bz-transaction.c @@ -761,14 +761,14 @@ tracker_update (BzTransactionPrivate *priv, g_autoptr (BzTransactionEntryTracker) tracker = NULL; gboolean result = FALSE; - entry = bz_backend_transaction_op_payload_get_entry (payload); - + entry = bz_backend_transaction_op_payload_get_entry (payload); result = find_and_maybe_transfer ( priv->trackers, NULL, entry, (GEqualFuncFull) find_entry_eq_func, (gpointer *) &tracker); + if (result) { if (transfer) @@ -776,11 +776,12 @@ tracker_update (BzTransactionPrivate *priv, GListModel *from = NULL; GListModel *to = NULL; - if (set_done) { - bz_transaction_entry_tracker_set_active (tracker, FALSE); - bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_DONE); - bz_transaction_entry_tracker_set_pending (tracker, FALSE); - } + if (set_done) + { + bz_transaction_entry_tracker_set_active (tracker, FALSE); + bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_DONE); + bz_transaction_entry_tracker_set_pending (tracker, FALSE); + } from = bz_transaction_entry_tracker_get_current_ops (tracker); to = bz_transaction_entry_tracker_get_finished_ops (tracker); @@ -798,8 +799,14 @@ tracker_update (BzTransactionPrivate *priv, { if (progress_payload != NULL) { + double progress = 0.0; + double scaled = 0.0; + + progress = bz_backend_transaction_op_progress_payload_get_total_progress (progress_payload); + scaled = progress >= 1.0 ? 1.0 : progress * 0.9; + g_object_set (tracker, - "progress", bz_backend_transaction_op_progress_payload_get_total_progress (progress_payload), + "progress", scaled, "pending", bz_backend_transaction_op_progress_payload_get_is_estimating (progress_payload), NULL); } From abd3ec36d88972af01bf2fd673ef0a9aa596078c Mon Sep 17 00:00:00 2001 From: Eva M Date: Mon, 20 Apr 2026 15:42:07 -0700 Subject: [PATCH 13/16] adjust inactive state indicator pill dimensions --- src/bz-install-controls.wdgt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index 44b4f6fd..0dac9d11 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -59,9 +59,9 @@ defwidget "Install Button" { state-default "inactive" { set stack:visible-child = btn-install; - set x = #eval((#(%width%)-#(w))/2.0); - set w = #eval(#(b)*2.0); - set b = #eval(#(%height%)/3.0); + set x = 0.0; + set w = %width%; + set b = 0.0; set opacity = 0.0; transition-spring x 1.0, 0.1, 10.0; From 49eb322dea53974fc626c8a83f0da0b227fb7632 Mon Sep 17 00:00:00 2001 From: Eva M Date: Mon, 20 Apr 2026 15:44:14 -0700 Subject: [PATCH 14/16] formatting --- src/bz-install-controls.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index 413983f8..24ac0486 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -67,9 +67,9 @@ static guint signals[LAST_SIGNAL]; static void update_tracker (BzInstallControls *self) { - BzTransactionManager *manager = NULL; - g_autoptr (GListModel) all = NULL; - const char *group_id = NULL; + BzTransactionManager *manager = NULL; + g_autoptr (GListModel) all = NULL; + const char *group_id = NULL; g_autoptr (BzTransactionEntryTracker) found = NULL; if (self->state != NULL) @@ -84,7 +84,7 @@ update_tracker (BzInstallControls *self) for (guint i = 0; i < g_list_model_get_n_items (all); i++) { g_autoptr (BzTransactionEntryTracker) tracker = NULL; - BzEntry *entry = NULL; + BzEntry *entry = NULL; tracker = g_list_model_get_item (all, i); entry = bz_transaction_entry_tracker_get_entry (tracker); @@ -517,8 +517,8 @@ bz_install_controls_set_state (BzInstallControls *self, if (self->state != NULL) { - BzTransactionManager *old_mgr = NULL; - g_autoptr (GListModel) all = NULL; + BzTransactionManager *old_mgr = NULL; + g_autoptr (GListModel) all = NULL; old_mgr = bz_state_info_get_transaction_manager (self->state); if (old_mgr != NULL) @@ -531,7 +531,7 @@ bz_install_controls_set_state (BzInstallControls *self, if (state != NULL) { - BzTransactionManager *mgr = NULL; + BzTransactionManager *mgr = NULL; g_autoptr (GListModel) all = NULL; mgr = bz_state_info_get_transaction_manager (state); From 72a8f1e722388107ae960e45ac831b6270b1f1b6 Mon Sep 17 00:00:00 2001 From: Eva M Date: Mon, 20 Apr 2026 15:50:46 -0700 Subject: [PATCH 15/16] reduce width of pending pill --- src/bz-install-controls.wdgt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index 0dac9d11..44441968 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -74,7 +74,7 @@ defwidget "Install Button" { set stack:visible-child = btn-cancel; set x = #eval((0.5+0.5*sin(3.0*#(%tick%))) * (#(%width%)-#(w))); - set w = #eval(#(%width%)*0.8); + set w = #eval(#(%width%)*0.7); set b = #eval(#(%height%)*0.175); set opacity = 1.0; From 61879d4795f6742d1c045b6d54f36f979012bc64 Mon Sep 17 00:00:00 2001 From: Eva M Date: Thu, 23 Apr 2026 04:34:27 -0700 Subject: [PATCH 16/16] add "cancelling" state --- src/bz-install-controls.blp | 1 + src/bz-install-controls.c | 19 +++++++++++-------- src/bz-install-controls.wdgt | 23 +++++++++++++++++++++++ src/bz-transaction.c | 7 ++++++- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/bz-install-controls.blp b/src/bz-install-controls.blp index 678228c1..75e59181 100644 --- a/src/bz-install-controls.blp +++ b/src/bz-install-controls.blp @@ -26,6 +26,7 @@ template $BzInstallControls: Box { reference: bind template.tracker as <$BzTransactionEntryTracker>; state: bind try { $get_install_btn_state( + template.tracker as <$BzTransactionEntryTracker>.status as <$BzTransactionEntryStatus>, template.tracker as <$BzTransactionEntryTracker>.active as , template.tracker as <$BzTransactionEntryTracker>.pending as , template.tracker as <$BzTransactionEntryTracker>.progress as diff --git a/src/bz-install-controls.c b/src/bz-install-controls.c index 24ac0486..1eec4855 100644 --- a/src/bz-install-controls.c +++ b/src/bz-install-controls.c @@ -231,17 +231,20 @@ get_visible_page (gpointer object, } static char * -get_install_btn_state (gpointer object, - gboolean active, - gboolean pending, - double progress) +get_install_btn_state (gpointer object, + BzTransactionEntryStatus status, + gboolean active, + gboolean pending, + double progress) { - if (pending) + if ((active || pending) && status == BZ_TRANSACTION_ENTRY_STATUS_CANCELLED) + return g_strdup ("cancelling"); + else if (pending || status == BZ_TRANSACTION_ENTRY_STATUS_QUEUED) return g_strdup ("pending"); - else if (active) - return g_strdup ("fraction"); - else + else if (!active || status == BZ_TRANSACTION_ENTRY_STATUS_DONE) return g_strdup ("inactive"); + else + return g_strdup ("fraction"); } static gboolean diff --git a/src/bz-install-controls.wdgt b/src/bz-install-controls.wdgt index 44441968..9ccbed69 100644 --- a/src/bz-install-controls.wdgt +++ b/src/bz-install-controls.wdgt @@ -4,6 +4,7 @@ defwidget "Install Button" { var btn-install : "GtkButton"; var btn-cancel : "GtkButton"; + var btn-cancelling : "GtkButton"; var bg : "GtkFixed"; var stack : "GtkStack"; @@ -37,6 +38,14 @@ defwidget "Install Button" { margin-start = 4; margin-end = 4; ); + %set btn-cancelling = #child/GtkButton(""("pill") + sensitive = false; + label = "Cancelling"; + margin-top = 4; + margin-bottom = 4; + margin-start = 4; + margin-end = 4; + ); ); allocate stack %width%, %height%, #(); set bg = #child/("" ("install-button" "install-button-indicator") @@ -97,4 +106,18 @@ defwidget "Install Button" { transition-spring b 1.1, 0.1, 100.0; transition-spring opacity 1.1, 0.1, 10.0; } + + state "cancelling" { + set stack:visible-child = btn-cancelling; + + set x = #eval((#(%width%)-#(w))/2.0); + set w = #eval(#(%width%)*0.8); + set b = #eval(#(%height%)*0.175); + set opacity = 0.0; + + transition-spring x 0.95, 0.25, 50.0; + transition-spring w 0.95, 0.25, 50.0; + transition-spring b 0.95, 0.25, 50.0; + transition-spring opacity 1.0, 1.0, 50.0; + } } diff --git a/src/bz-transaction.c b/src/bz-transaction.c index ae2bdcb5..b4173d36 100644 --- a/src/bz-transaction.c +++ b/src/bz-transaction.c @@ -771,6 +771,9 @@ tracker_update (BzTransactionPrivate *priv, if (result) { + BzTransactionEntryStatus existing_status = 0; + + existing_status = bz_transaction_entry_tracker_get_status (tracker); if (transfer) { GListModel *from = NULL; @@ -811,7 +814,9 @@ tracker_update (BzTransactionPrivate *priv, NULL); } bz_transaction_entry_tracker_set_active (tracker, TRUE); - bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_ONGOING); + + if (existing_status != BZ_TRANSACTION_ENTRY_STATUS_CANCELLED) + bz_transaction_entry_tracker_set_status (tracker, BZ_TRANSACTION_ENTRY_STATUS_ONGOING); } } }