diff --git a/.gitignore b/.gitignore index 5053a6d..f1c3efc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ build builddir .flatpak-builder *~ +.flatpak +.vscode \ No newline at end of file diff --git a/com.github.elfenware.obliviate.yml b/com.github.elfenware.obliviate.yml index 29142ce..b2d078a 100644 --- a/com.github.elfenware.obliviate.yml +++ b/com.github.elfenware.obliviate.yml @@ -1,13 +1,14 @@ app-id: com.github.elfenware.obliviate runtime: io.elementary.Platform -runtime-version: '7' +runtime-version: '8.2' sdk: io.elementary.Sdk command: com.github.elfenware.obliviate finish-args: - '--share=ipc' + - '--device=dri' - '--socket=fallback-x11' - '--socket=wayland' @@ -18,6 +19,15 @@ modules: - type: archive url: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.8.8.tar.bz2 sha256: 895de2bb981dd127f0821d1ce13fadf7d760f9fa7737648b15f2c1fe13cc5af5 + modules: + - name: libgpg-error + buildsystem: autotools + config-opts: + - "--enable-install-gpg-error-config" + sources: + - type: archive + url: https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.55.tar.gz + sha256: bda09f51d7ed64565e41069d782bfcc4984aed908ae68bee01fb692b64ea96e2 - name: obliviate buildsystem: meson sources: diff --git a/data/com.github.elfenware.obliviate.appdata.xml.in b/data/com.github.elfenware.obliviate.metainfo.xml.in similarity index 96% rename from data/com.github.elfenware.obliviate.appdata.xml.in rename to data/com.github.elfenware.obliviate.metainfo.xml.in index 131a69c..4739117 100644 --- a/data/com.github.elfenware.obliviate.appdata.xml.in +++ b/data/com.github.elfenware.obliviate.metainfo.xml.in @@ -19,6 +19,13 @@

Bonus: If you need your passwords on another device, you can get them on the web from obliviate.app.

+ + +
    +
  • Move to modern tech
  • +
+
+
    diff --git a/data/meson.build b/data/meson.build index a5e6012..7a6e922 100644 --- a/data/meson.build +++ b/data/meson.build @@ -16,7 +16,7 @@ endforeach i18n.merge_file ( input: meson.project_name () + '.desktop.in', output: meson.project_name () + '.desktop', - po_dir: join_paths (meson.source_root (), 'po', 'extra'), + po_dir: join_paths (meson.project_source_root (), 'po', 'extra'), type: 'desktop', install: true, install_dir: join_paths (get_option ('datadir'), 'applications') @@ -24,9 +24,9 @@ i18n.merge_file ( # Translate and install our .appdata.xml file so AppCenter will see it i18n.merge_file ( - input: meson.project_name () + '.appdata.xml.in', - output: meson.project_name () + '.appdata.xml', - po_dir: join_paths (meson.source_root (), 'po', 'extra'), + input: meson.project_name () + '.metainfo.xml.in', + output: meson.project_name () + '.metainfo.xml', + po_dir: join_paths (meson.project_source_root (), 'po', 'extra'), install: true, install_dir: join_paths (get_option ('datadir'), 'metainfo') ) diff --git a/meson.build b/meson.build index 4fde3f4..af149d4 100644 --- a/meson.build +++ b/meson.build @@ -2,7 +2,7 @@ project ( 'com.github.elfenware.obliviate', 'vala', 'c', - version: '2.4.0' + version: '3.0.0' ) # Translation module @@ -38,9 +38,8 @@ asresources = gnome.compile_resources ( # Listing dependencies dependencies = [ dependency ('glib-2.0'), - dependency ('granite'), - dependency ('gtk+-3.0'), - dependency ('libhandy-1'), + dependency ('granite-7'), + dependency ('gtk4'), declare_dependency (dependencies: [ meson.get_compiler ('c').find_library ('libgcrypt'), meson.get_compiler ('vala').find_library ('gcrypt', dirs: join_paths (meson.current_source_dir (), 'vapi')) @@ -62,4 +61,8 @@ executable ( subdir('data') subdir('po') -meson.add_install_script ('meson/post_install.py') +gnome.post_install( + glib_compile_schemas: true, + gtk_update_icon_cache: true, + update_desktop_database: true + ) diff --git a/meson/post_install.py b/meson/post_install.py deleted file mode 100644 index 56fde7d..0000000 --- a/meson/post_install.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python3 - -from os import path, environ -import subprocess - -prefix = environ.get('MESON_INSTALL_PREFIX', '/usr') -schemadir = path.join(environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas') -datadir = path.join(prefix, 'share') -desktop_database_dir = path.join(datadir, 'applications') - -if not environ.get('DESTDIR'): - print('Compiling gsettings schemas…') - subprocess.call(['glib-compile-schemas', schemadir]) - print('Updating desktop database…') - subprocess.call(['update-desktop-database', '-q', desktop_database_dir]) - print('Updating icon cache…') - subprocess.call(['gtk-update-icon-cache', '-qtf', path.join(datadir, 'icons', 'hicolor')]) diff --git a/po/extra/meson.build b/po/extra/meson.build index 526e40f..807f893 100644 --- a/po/extra/meson.build +++ b/po/extra/meson.build @@ -1,7 +1,7 @@ # Install metadata translations i18n.gettext ('extra', args: [ - '--directory=' + meson.source_root (), + '--directory=' + meson.project_source_root (), '--from-code=UTF-8' ], install: false diff --git a/po/meson.build b/po/meson.build index 011a4ae..902b019 100644 --- a/po/meson.build +++ b/po/meson.build @@ -1,7 +1,7 @@ # Install main translations i18n.gettext (meson.project_name (), args: [ - '--directory=' + meson.source_root (), + '--directory=' + meson.project_source_root (), '--from-code=UTF-8', '-cTRANSLATORS' ], diff --git a/src/Application.vala b/src/Application.vala index 0942ac9..3055894 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -18,7 +18,7 @@ * */ -public class Obliviate.Application : Granite.Application { +public class Obliviate.Application : Gtk.Application { private Obliviate.MainWindow window; public Application () { @@ -52,8 +52,8 @@ public class Obliviate.Application : Granite.Application { var provider = new Gtk.CssProvider (); provider.load_from_resource ("/com/github/elfenware/obliviate/Application.css"); - Gtk.StyleContext.add_provider_for_screen ( - Gdk.Screen.get_default (), + Gtk.StyleContext.add_provider_for_display ( + Gdk.Display.get_default (), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ); diff --git a/src/MainView.vala b/src/MainView.vala index e0de12f..608c590 100644 --- a/src/MainView.vala +++ b/src/MainView.vala @@ -18,35 +18,40 @@ * */ -public class Obliviate.MainView : Gtk.Overlay { +public class Obliviate.MainView : Gtk.Box { + private Gtk.Overlay overlay; private Gtk.Grid grid; - private Granite.Widgets.Toast toast; + private Granite.Toast toast; private Gtk.Entry site; - private Gtk.Entry cipher_key; - private Gtk.Entry generated_pass; - private Gtk.ToggleButton show_generated_pass; + private Gtk.PasswordEntry cipher_key; + private Gtk.PasswordEntry generated_pass; private Gtk.Button copy_btn; private Gtk.Button copy_without_symbols_btn; private Gtk.Label clearing_label; private Gtk.ProgressBar clearing_progress; - private Gtk.Clipboard clipboard; + private Gdk.Clipboard clipboard; private const float CLIPBOARD_LIFE = 30; private uint timeout_id; construct { + overlay = new Gtk.Overlay(); + grid = new Gtk.Grid () { row_spacing = 4, column_spacing = 4, - margin = 30, + margin_top = 30, + margin_bottom = 30, + margin_start = 30, + margin_end = 30, halign = Gtk.Align.CENTER }; - toast = new Granite.Widgets.Toast (_ ("Copied to clipboard")); + var toast = new Granite.Toast (_ ("Copied to clipboard")); - add (grid); - add_overlay (toast); + overlay.set_child (grid); + overlay.add_overlay (toast); var site_label = new Gtk.Label (_ ("Site:")) { halign = Gtk.Align.END, @@ -54,61 +59,40 @@ public class Obliviate.MainView : Gtk.Overlay { }; site = new Gtk.Entry () { - placeholder_text = _ ("GitHub") + placeholder_text = _ ("GitHub"), + primary_icon_name = "dialog-information-symbolic", + primary_icon_tooltip_text = "Site is not case-sensitive. “GitHub” equals “github”." }; site.changed.connect (handle_generate_password); - var site_info = new Gtk.Image.from_icon_name ("dialog-information-symbolic", Gtk.IconSize.MENU) { - tooltip_text = _ ("Site is not case-sensitive. “GitHub” equals “github”.") - }; - var cipher_key_label = new Gtk.Label (_ ("Cipher key:")) { halign = Gtk.Align.END, margin_end = 4 }; - // TODO: replace with Gtk.PasswordEntry after updating to Gtk4 - cipher_key = new Gtk.Entry () { - visibility = false, - caps_lock_warning = true, - input_purpose = Gtk.InputPurpose.PASSWORD, + cipher_key = new Gtk.PasswordEntry () { + show_peek_icon = true, placeholder_text = _ ("correct horse battery staple"), width_chars = 24 }; cipher_key.changed.connect (handle_generate_password); - var show_cipher_key = new Gtk.ToggleButton () { - active = true, - tooltip_text = _ ("Show or hide the cipher key") - }; - - show_cipher_key.add (new Gtk.Image.from_icon_name ("image-red-eye-symbolic", Gtk.IconSize.BUTTON)); - show_cipher_key.bind_property ("active", cipher_key, "visibility", BindingFlags.INVERT_BOOLEAN); - - generated_pass = new Gtk.Entry () { - visibility = false, + this.generated_pass = new Gtk.PasswordEntry () { + show_peek_icon = true, editable = false, - sensitive = false - }; - - generated_pass.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); - - show_generated_pass = new Gtk.ToggleButton () { - active = true, - tooltip_text = _ ("Show or hide the password"), - sensitive = false + sensitive = false, + width_chars = 24 }; - show_generated_pass.add (new Gtk.Image.from_icon_name ("image-red-eye-symbolic", Gtk.IconSize.BUTTON)); - show_generated_pass.bind_property ("active", generated_pass, "visibility", BindingFlags.INVERT_BOOLEAN); + this.generated_pass.add_css_class (Granite.STYLE_CLASS_FLAT); copy_btn = new Gtk.Button.with_label (_ ("Copy")) { sensitive = false }; - copy_btn.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + copy_btn.add_css_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); copy_btn.clicked.connect (() => { handle_copy (); @@ -123,8 +107,8 @@ public class Obliviate.MainView : Gtk.Overlay { }); var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - button_box.pack_start (copy_btn); - button_box.pack_end (copy_without_symbols_btn); + button_box.prepend (copy_btn); + button_box.append (copy_without_symbols_btn); clearing_label = new Gtk.Label (ngettext ( "Clearing clipboard in %.0f second", @@ -140,37 +124,35 @@ public class Obliviate.MainView : Gtk.Overlay { fraction = 1 }; - clearing_progress.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); + clearing_progress.add_css_class (Granite.STYLE_CLASS_FLAT); var plus_label = new Gtk.Label ("+"); - plus_label.get_style_context ().add_class ("sign"); + plus_label.add_css_class ("sign"); var equals_label = new Gtk.Label ("="); - equals_label.get_style_context ().add_class ("sign"); + equals_label.add_css_class ("sign"); grid.attach (site_label, 0, 0, 1, 1); grid.attach_next_to (site, site_label, Gtk.PositionType.RIGHT); - grid.attach_next_to (site_info, site, Gtk.PositionType.RIGHT); grid.attach_next_to (plus_label, site, Gtk.PositionType.BOTTOM); grid.attach (cipher_key_label, 0, 2, 1, 1); grid.attach_next_to (cipher_key, cipher_key_label, Gtk.PositionType.RIGHT); - grid.attach_next_to (show_cipher_key, cipher_key, Gtk.PositionType.RIGHT); grid.attach_next_to (equals_label, cipher_key, Gtk.PositionType.BOTTOM); grid.attach_next_to (generated_pass, equals_label, Gtk.PositionType.BOTTOM); - grid.attach_next_to (show_generated_pass, generated_pass, Gtk.PositionType.RIGHT); grid.attach_next_to (button_box, generated_pass, Gtk.PositionType.BOTTOM); - clipboard = Gtk.Clipboard.get_default (Gdk.Display.get_default ()); + clipboard = this.get_clipboard (); + + append (overlay); } private void handle_generate_password () { if (site.text.length == 0 || cipher_key.text.length == 0) { generated_pass.text = ""; - show_generated_pass.sensitive = false; copy_btn.sensitive = false; copy_without_symbols_btn.sensitive = false; return; @@ -178,7 +160,6 @@ public class Obliviate.MainView : Gtk.Overlay { try { generated_pass.text = Service.derive_password (cipher_key.text, site.text.down ()); - show_generated_pass.sensitive = true; copy_btn.sensitive = true; copy_without_symbols_btn.sensitive = true; animate_password (); @@ -195,7 +176,7 @@ public class Obliviate.MainView : Gtk.Overlay { ? Service.remove_symbols (generated_pass.text) : generated_pass.text; - clipboard.set_text (text_to_copy, generated_pass.text.length); + clipboard.set_text (text_to_copy); toast.title = _ ("Copied to clipboard"); toast.send_notification (); @@ -205,7 +186,7 @@ public class Obliviate.MainView : Gtk.Overlay { float seconds_left = CLIPBOARD_LIFE; timeout_id = Timeout.add_seconds (1, () => { if (seconds_left == 0) { - clipboard.clear (); + clipboard.set_text (""); toast.title = _ ("Cleared the clipboard"); toast.send_notification (); @@ -242,10 +223,9 @@ public class Obliviate.MainView : Gtk.Overlay { } private void animate_password () { - var password_style = generated_pass.get_style_context (); - password_style.add_class ("regenerating"); + generated_pass.add_css_class ("regenerating"); Timeout.add (100, () => { - password_style.remove_class ("regenerating"); + generated_pass.remove_css_class ("regenerating"); return false; }); } diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 5370209..fefbfd9 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -18,7 +18,7 @@ * */ -public class Obliviate.MainWindow : Hdy.ApplicationWindow { +public class Obliviate.MainWindow : Gtk.Window { private GLib.Settings settings; public MainWindow (Gtk.Application app) { @@ -26,48 +26,37 @@ public class Obliviate.MainWindow : Hdy.ApplicationWindow { } construct { - Hdy.init (); - var header = get_header (); + var headerbar = get_headerbar (); var main = new MainView (); var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - box.add (header); - box.add (main); - add (box); + box.append (headerbar); + box.append (main); + set_child (box); - set_geometry_hints (null, Gdk.Geometry () { - min_width = 440, - min_height = 280 - }, Gdk.WindowHints.MIN_SIZE); + set_size_request (440, 280); settings = new GLib.Settings ("com.github.elfenware.obliviate.state"); - int default_x = settings.get_int ("window-x"); - int default_y = settings.get_int ("window-y"); + set_default_size (settings.get_int ("window-width"), settings.get_int ("window-height")); - if (default_x != -1 && default_y != -1) { - move (default_x, default_y); - } + show (); - resize (settings.get_int ("window-width"), settings.get_int ("window-height")); - - show_all (); - - delete_event.connect (e => { + this.close_request.connect (e => { return before_destroy (); }); } - private Hdy.HeaderBar get_header () { - var header = new Hdy.HeaderBar () { - title = "Obliviate", - has_subtitle = false, - show_close_button = true - }; + private Gtk.HeaderBar get_headerbar () { + set_title (_("Obliviate")); + Gtk.Label title_widget = new Gtk.Label (_("Obliviate")); + title_widget.add_css_class (Granite.STYLE_CLASS_TITLE_LABEL); - header.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); - header.get_style_context ().add_class ("headerbar"); + var headerbar = new Gtk.HeaderBar (); + headerbar.set_title_widget (title_widget); + headerbar.add_css_class (Granite.STYLE_CLASS_FLAT); + set_titlebar (headerbar); var help_btn = new Gtk.Button.from_icon_name ("help-contents") { tooltip_text = _("Help and FAQ") @@ -81,19 +70,16 @@ public class Obliviate.MainWindow : Hdy.ApplicationWindow { } }); - header.pack_end (help_btn); + headerbar.pack_end (help_btn); - return header; + return headerbar; } private bool before_destroy () { - int x, y, width, height; + int width, height; - get_position (out x, out y); - get_size (out width, out height); + get_default_size (out width, out height); - settings.set_int ("window-x", x); - settings.set_int ("window-y", y); settings.set_int ("window-width", width); settings.set_int ("window-height", height); diff --git a/src/Service.vala b/src/Service.vala index 53e35cb..37642a2 100644 --- a/src/Service.vala +++ b/src/Service.vala @@ -62,7 +62,15 @@ public class Obliviate.Service : GLib.Object { } public static string remove_symbols (string str) { - var regex = new Regex ("[^a-zA-Z0-9]"); - return regex.replace (str, str.length, 0, ""); + Regex regex; + + try { + regex = new Regex ("[^a-zA-Z0-9]"); + return regex.replace (str, str.length, 0, ""); + } catch (Error e) { + debug ("Error removing symbols."); + } + + return str; } } diff --git a/vapi/config.vapi b/vapi/config.vapi new file mode 100644 index 0000000..628ef9d --- /dev/null +++ b/vapi/config.vapi @@ -0,0 +1,10 @@ +[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")] +namespace Build { + public const string DATADIR; + public const string PKGDATADIR; + public const string GETTEXT_PACKAGE; + public const string RELEASE_NAME; + public const string VERSION; + public const string VERSION_INFO; + public const string PLUGINDIR; +}