diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 11a2c1a..0655467 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -23,7 +23,7 @@ jobs:
- name: Install Dependencies
run: |
apt update
- apt install -y libgranite-dev systemd-dev meson valac
+ apt install -y libgranite-7-dev systemd-dev meson valac
- name: Build
env:
DESTDIR: out
diff --git a/README.md b/README.md
index 51c9a31..37fdb4c 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,8 @@ Send and receive files via Bluetooth
You'll need the following dependencies:
- libgranite-dev >= 6.0.0
- libgtk3-dev
+ libgranite-7-dev >= 7.7.0
+ libgtk-4-dev
systemd-dev
meson
valac
diff --git a/meson.build b/meson.build
index 4cf94a8..9f8785f 100644
--- a/meson.build
+++ b/meson.build
@@ -13,8 +13,8 @@ i18n = import('i18n')
prefix = get_option('prefix')
bindir = prefix / get_option('bindir')
-granite_dep = dependency ('granite')
-gtk_dep = dependency ('gtk+-3.0')
+granite_dep = dependency ('granite-7', version: '>=7.7.0')
+gtk_dep = dependency ('gtk4')
posix_dep = meson.get_compiler('vala').find_library('posix')
subdir('data')
diff --git a/src/Application.vala b/src/Application.vala
index 577984d..fd3919e 100644
--- a/src/Application.vala
+++ b/src/Application.vala
@@ -48,8 +48,9 @@ public class BluetoothApp : Gtk.Application {
if (bt_scan == null) {
bt_scan = new ScanDialog (this, object_manager);
- bt_scan.destroy.connect (() => {
+ bt_scan.close_request.connect (() => {
bt_scan = null;
+ return Gdk.EVENT_PROPAGATE;
});
bt_scan.send_file.connect ((device) => {
@@ -58,12 +59,13 @@ public class BluetoothApp : Gtk.Application {
bt_sender.add_files (files, device);
bt_senders.append (bt_sender);
bt_sender.present ();
- bt_sender.destroy.connect (() => {
+ bt_sender.close_request.connect (() => {
bt_senders.foreach ((sender) => {
if (sender.device == bt_sender.device) {
bt_senders.remove_link (bt_senders.find (sender));
}
});
+ return Gdk.EVENT_PROPAGATE;
});
}
});
@@ -234,7 +236,7 @@ public class BluetoothApp : Gtk.Application {
bt_receiver = new ReceiverDialog (this);
bt_receivers.append (bt_receiver);
- bt_receiver.destroy.connect (() => {
+ ((Gtk.Widget) bt_receiver).destroy.connect (() => {
bt_receivers.foreach ((receiver) => {
if (receiver.transfer.session == bt_receiver.session) {
bt_receivers.remove_link (bt_receivers.find (receiver));
diff --git a/src/Dialog/DeviceRow.vala b/src/Dialog/DeviceRow.vala
index 7d6d71d..792b088 100644
--- a/src/Dialog/DeviceRow.vala
+++ b/src/Dialog/DeviceRow.vala
@@ -28,9 +28,11 @@ public class DeviceRow : Gtk.ListBoxRow {
}
construct {
- var image = new Gtk.Image.from_icon_name (device.icon ?? "bluetooth", DND);
+ var image = new Gtk.Image.from_icon_name (device.icon ?? "bluetooth") {
+ icon_size = LARGE
+ };
- state = new Gtk.Image.from_icon_name ("emblem-disabled", MENU) {
+ state = new Gtk.Image.from_icon_name ("emblem-disabled") {
halign = END,
valign = END
};
@@ -38,7 +40,7 @@ public class DeviceRow : Gtk.ListBoxRow {
var state_label = new Gtk.Label (null) {
xalign = 0
};
- state_label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL);
+ state_label.add_css_class (Granite.CssClass.SMALL);
var overlay = new Gtk.Overlay () {
child = image,
@@ -81,7 +83,6 @@ public class DeviceRow : Gtk.ListBoxRow {
grid.attach (send_button, 4, 0, 1, 2);
child = grid;
- show_all ();
set_sensitive (adapter.powered);
set_status (device.connected);
@@ -114,7 +115,7 @@ public class DeviceRow : Gtk.ListBoxRow {
send_button.clicked.connect (() => {
send_file (device);
- get_toplevel ().destroy ();
+ get_root ().destroy ();
});
}
diff --git a/src/Dialog/ReceiverDialog.vala b/src/Dialog/ReceiverDialog.vala
index ae44e40..960dbf6 100644
--- a/src/Dialog/ReceiverDialog.vala
+++ b/src/Dialog/ReceiverDialog.vala
@@ -32,7 +32,8 @@ public class ReceiverDialog : Granite.Dialog {
notification = new GLib.Notification ("bluetooth");
notification.set_priority (NotificationPriority.NORMAL);
- var icon_image = new Gtk.Image.from_icon_name ("io.elementary.bluetooth", Gtk.IconSize.DIALOG) {
+ var icon_image = new Gtk.Image.from_icon_name ("io.elementary.bluetooth") {
+ pixel_size = 48,
valign = END,
halign = END
};
@@ -54,7 +55,7 @@ public class ReceiverDialog : Granite.Dialog {
wrap = true,
xalign = 0
};
- device_label.get_style_context ().add_class ("primary");
+ device_label.add_css_class ("primary");
directory_label = new Gtk.Label (null) {
max_width_chars = 45,
@@ -101,14 +102,13 @@ public class ReceiverDialog : Granite.Dialog {
message_grid.attach (rate_label, 1, 3);
message_grid.attach (progressbar, 1, 4);
message_grid.attach (progress_label, 1, 5);
- message_grid.show_all ();
- get_content_area ().add (message_grid);
+ get_content_area ().append (message_grid);
add_button (_("Close"), Gtk.ResponseType.CLOSE);
var suggested_button = add_button (_("Reject"), Gtk.ResponseType.ACCEPT);
- suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION);
+ suggested_button.add_css_class (Granite.CssClass.DESTRUCTIVE);
response.connect ((response_id) => {
if (response_id == Gtk.ResponseType.ACCEPT) {
@@ -117,18 +117,9 @@ public class ReceiverDialog : Granite.Dialog {
} catch (Error e) {
GLib.warning (e.message);
}
- destroy ();
- } else {
- hide_on_delete ();
}
- });
- delete_event.connect (() => {
- if (transfer.status == "active") {
- return hide_on_delete ();
- } else {
- return false;
- }
+ close ();
});
}
@@ -152,6 +143,8 @@ public class ReceiverDialog : Granite.Dialog {
}
private void tranfer_progress () {
+ hide_on_close = transfer.status == "active";
+
try {
switch (transfer.status) {
case "error":
@@ -159,7 +152,7 @@ public class ReceiverDialog : Granite.Dialog {
notification.set_title (_("File transfer failed"));
notification.set_body (GLib.Markup.printf_escaped (_("%s File: %s not received"), device_label.get_label (), transfer.name));
Application.get_default ().send_notification ("io.elementary.bluetooth", notification);
- destroy ();
+ close ();
break;
case "queued":
break;
@@ -172,7 +165,7 @@ public class ReceiverDialog : Granite.Dialog {
break;
case "complete":
move_to_folder (path_folder);
- destroy ();
+ close ();
break;
}
} catch (Error e) {
diff --git a/src/Dialog/ScanDialog.vala b/src/Dialog/ScanDialog.vala
index 98c9ccb..a16044e 100644
--- a/src/Dialog/ScanDialog.vala
+++ b/src/Dialog/ScanDialog.vala
@@ -23,7 +23,8 @@ public class ScanDialog : Granite.Dialog {
}
construct {
- var icon_image = new Gtk.Image.from_icon_name ("io.elementary.bluetooth", Gtk.IconSize.DIALOG) {
+ var icon_image = new Gtk.Image.from_icon_name ("io.elementary.bluetooth") {
+ pixel_size = 48,
valign = CENTER,
halign = CENTER
};
@@ -34,7 +35,7 @@ public class ScanDialog : Granite.Dialog {
wrap = true,
xalign = 0
};
- title_label.get_style_context ().add_class ("primary");
+ title_label.add_css_class ("primary");
var info_label = new Gtk.Label (_("Select a Bluetooth Device Below to Send Files")) {
max_width_chars = 45,
@@ -43,12 +44,9 @@ public class ScanDialog : Granite.Dialog {
xalign = 0
};
- var empty_alert = new Granite.Widgets.AlertView (
- _("No Devices Found"),
- _("Please ensure that your devices are visible and ready for pairing."),
- ""
- );
- empty_alert.show_all ();
+ var empty_alert = new Granite.Placeholder (_("No Devices Found")) {
+ description = _("Please ensure that your devices are visible and ready for pairing.")
+ };
list_box = new Gtk.ListBox () {
activate_on_single_click = true,
@@ -57,8 +55,9 @@ public class ScanDialog : Granite.Dialog {
list_box.set_sort_func ((Gtk.ListBoxSortFunc) compare_rows);
list_box.set_placeholder (empty_alert);
- var scrolled = new Gtk.ScrolledWindow (null, null) {
+ var scrolled = new Gtk.ScrolledWindow () {
child = list_box,
+ has_frame = true,
hexpand = true,
vexpand = true,
hscrollbar_policy = NEVER,
@@ -67,13 +66,12 @@ public class ScanDialog : Granite.Dialog {
max_content_height = 350,
propagate_natural_height = true
};
- scrolled.get_style_context ().add_class (Gtk.STYLE_CLASS_FRAME);
var overlay = new Gtk.Overlay () {
child = scrolled
};
- var overlaybar = new Granite.Widgets.OverlayBar (overlay) {
+ var overlaybar = new Granite.OverlayBar (overlay) {
label = _("Discovering")
};
@@ -87,10 +85,10 @@ public class ScanDialog : Granite.Dialog {
var content_box = new Gtk.Box (VERTICAL, 0) {
valign = CENTER
};
- content_box.add (image_grid);
- content_box.add (overlay);
+ content_box.append (image_grid);
+ content_box.append (overlay);
- get_content_area ().add (content_box);
+ get_content_area ().append (content_box);
manager.device_added.connect (add_device);
manager.device_removed.connect (device_removed);
@@ -102,7 +100,7 @@ public class ScanDialog : Granite.Dialog {
response.connect ((response_id) => {
manager.stop_discovery.begin ();
- destroy ();
+ close ();
});
}
@@ -124,7 +122,7 @@ public class ScanDialog : Granite.Dialog {
}
var row = new DeviceRow (device, manager.get_adapter_from_path (device.adapter));
- list_box.add (row);
+ list_box.append (row);
if (list_box.get_selected_row () == null) {
list_box.select_row (row);
diff --git a/src/Dialog/SenderDialog.vala b/src/Dialog/SenderDialog.vala
index 81270ef..2ebbd33 100644
--- a/src/Dialog/SenderDialog.vala
+++ b/src/Dialog/SenderDialog.vala
@@ -37,7 +37,8 @@ public class SenderDialog : Granite.Dialog {
construct {
liststore = new Gtk.ListStore (1, typeof (File));
- var icon_image = new Gtk.Image.from_icon_name ("io.elementary.bluetooth", Gtk.IconSize.DIALOG) {
+ var icon_image = new Gtk.Image.from_icon_name ("io.elementary.bluetooth") {
+ pixel_size = 48,
valign = END,
halign = END
};
@@ -59,7 +60,7 @@ public class SenderDialog : Granite.Dialog {
wrap = true,
xalign = 0
};
- path_label.get_style_context ().add_class ("primary");
+ path_label.add_css_class ("primary");
device_label = new Gtk.Label (GLib.Markup.printf_escaped ("%s:", _("To"))) {
max_width_chars = 45,
@@ -106,43 +107,27 @@ public class SenderDialog : Granite.Dialog {
message_grid.attach (rate_label, 1, 3);
message_grid.attach (progressbar, 1, 4);
message_grid.attach (progress_label, 1, 5);
- message_grid.show_all ();
- get_content_area ().add (message_grid);
+ get_content_area ().append (message_grid);
add_button (_("Close"), Gtk.ResponseType.CLOSE);
var reject_transfer = add_button (_("Cancel"), Gtk.ResponseType.CANCEL);
- reject_transfer.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION);
+ reject_transfer.add_css_class (Granite.CssClass.DESTRUCTIVE);
response.connect ((response_id) => {
if (response_id == Gtk.ResponseType.CANCEL) {
- if (transfer != null) {
- if (transfer.status == "active") {
- try {
- transfer.cancel ();
- } catch (Error e) {
- GLib.warning (e.message);
- }
- remove_session.begin ();
+ if (transfer != null && transfer.status == "active") {
+ try {
+ transfer.cancel ();
+ } catch (Error e) {
+ GLib.warning (e.message);
}
- }
- destroy ();
- } else {
- if (transfer.status == "active") {
- hide_on_delete ();
- } else {
- destroy ();
+ remove_session.begin ();
}
}
- });
- delete_event.connect (() => {
- if (transfer.status == "active") {
- return hide_on_delete ();
- } else {
- return false;
- }
+ close ();
});
}
@@ -241,7 +226,7 @@ public class SenderDialog : Granite.Dialog {
);
send_file.begin ();
} catch (Error e) {
- hide_on_delete ();
+ hide ();
var bt_retry = new Granite.MessageDialog (
_("Connecting to '%s' failed.").printf (device.alias),
"%s\n%s".printf (
@@ -257,14 +242,14 @@ public class SenderDialog : Granite.Dialog {
};
bt_retry.add_button (_("Cancel"), Gtk.ResponseType.CANCEL);
var suggested_button = bt_retry.add_button (_("Retry"), Gtk.ResponseType.ACCEPT);
- suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ suggested_button.add_css_class (Granite.CssClass.SUGGESTED);
bt_retry.response.connect ((response_id) => {
if (response_id == Gtk.ResponseType.ACCEPT) {
create_session.begin ();
present ();
} else {
- destroy ();
+ close ();
}
bt_retry.destroy ();
@@ -306,9 +291,11 @@ public class SenderDialog : Granite.Dialog {
}
private void tranfer_progress () {
+ hide_on_close = transfer.status == "active";
+
switch (transfer.status) {
case "error":
- hide_on_delete ();
+ hide ();
var bt_retry = new Granite.MessageDialog (
_("The transfer of '%s' failed.").printf (file_path.get_basename ()),
"%s\n%s".printf (
@@ -324,7 +311,7 @@ public class SenderDialog : Granite.Dialog {
};
bt_retry.add_button (_("Cancel"), Gtk.ResponseType.CANCEL);
var suggested_button = bt_retry.add_button (_("Retry"), Gtk.ResponseType.ACCEPT);
- suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ suggested_button.add_css_class (Granite.CssClass.SUGGESTED);
bt_retry.response.connect ((response_id) => {
if (response_id == Gtk.ResponseType.ACCEPT) {
@@ -350,7 +337,7 @@ public class SenderDialog : Granite.Dialog {
send_notify ();
if (!next_file ()) {
remove_session.begin ();
- destroy ();
+ close ();
}
break;
}