From cd8575d6c56fc6b7d63273a7ad283adb8390e1c8 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 17:01:51 +0000 Subject: [PATCH 01/35] - First draft of locker --- meson.build | 2 + metadata/locker.xml | 351 ++++++++++++++++++++++++++++++ src/locker/locker.cpp | 226 +++++++++++++++++++ src/locker/locker.hpp | 58 +++++ src/locker/meson.build | 33 +++ src/locker/plugin.hpp | 63 ++++++ src/locker/plugin/battery.cpp | 241 ++++++++++++++++++++ src/locker/plugin/battery.hpp | 58 +++++ src/locker/plugin/clock.cpp | 66 ++++++ src/locker/plugin/clock.hpp | 29 +++ src/locker/plugin/fingerprint.cpp | 193 ++++++++++++++++ src/locker/plugin/fingerprint.hpp | 40 ++++ src/locker/plugin/instant.cpp | 35 +++ src/locker/plugin/instant.hpp | 23 ++ src/locker/plugin/password.cpp | 147 +++++++++++++ src/locker/plugin/password.hpp | 33 +++ src/locker/plugin/pin.cpp | 208 ++++++++++++++++++ src/locker/plugin/pin.hpp | 48 ++++ src/meson.build | 1 + src/util/css-config.cpp | 1 - src/util/css-config.hpp | 2 +- src/util/wf-shell-app.cpp | 24 +- src/util/wf-shell-app.hpp | 1 + subprojects/.wraplock | 0 24 files changed, 1871 insertions(+), 12 deletions(-) create mode 100644 metadata/locker.xml create mode 100644 src/locker/locker.cpp create mode 100644 src/locker/locker.hpp create mode 100644 src/locker/meson.build create mode 100644 src/locker/plugin.hpp create mode 100644 src/locker/plugin/battery.cpp create mode 100644 src/locker/plugin/battery.hpp create mode 100644 src/locker/plugin/clock.cpp create mode 100644 src/locker/plugin/clock.hpp create mode 100644 src/locker/plugin/fingerprint.cpp create mode 100644 src/locker/plugin/fingerprint.hpp create mode 100644 src/locker/plugin/instant.cpp create mode 100644 src/locker/plugin/instant.hpp create mode 100644 src/locker/plugin/password.cpp create mode 100644 src/locker/plugin/password.hpp create mode 100644 src/locker/plugin/pin.cpp create mode 100644 src/locker/plugin/pin.hpp create mode 100644 subprojects/.wraplock diff --git a/meson.build b/meson.build index f50bcee9..3c7b9a76 100644 --- a/meson.build +++ b/meson.build @@ -14,6 +14,7 @@ project( ) wayfire = dependency('wayfire') +pam = dependency('pam') wayland_client = dependency('wayland-client') wayland_protos = dependency('wayland-protocols') gtkmm = dependency('gtkmm-4.0', version: '>=4.12') @@ -25,6 +26,7 @@ dbusmenu_gtk = dependency('dbusmenu-glib-0.4') libgvc = subproject('gvc', default_options: ['static=true'], required: get_option('pulse')) xkbregistry = dependency('xkbregistry') json = subproject('wf-json').get_variable('wfjson') +openssl = dependency('openssl') if get_option('wayland-logout') == true wayland_logout = subproject('wayland-logout') diff --git a/metadata/locker.xml b/metadata/locker.xml new file mode 100644 index 00000000..740fc696 --- /dev/null +++ b/metadata/locker.xml @@ -0,0 +1,351 @@ + + + + <_short>Locker + Shell + + <_short>General + + + + <_short>Password + + + + + <_short>PIN + + + + + + + <_short>Fingerprint + + + + + + + <_short>Clock + + + + + + + <_short>Battery + + + + + + + + + <_short>Instant Unlock + + + + + + diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp new file mode 100644 index 00000000..706b3914 --- /dev/null +++ b/src/locker/locker.cpp @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "locker.hpp" + +#include "gdkmm/monitor.h" +#include "glibmm/miscutils.h" +#include "gtk4-session-lock.h" +#include "gtkmm/enums.h" + +#include "plugin/battery.hpp" +#include "plugin/clock.hpp" +#include "plugin/instant.hpp" +#include "plugin/password.hpp" +#include "plugin/pin.hpp" +#include "plugin/fingerprint.hpp" +#include "wf-shell-app.hpp" +#include + +WayfireLockerApp::~WayfireLockerApp(){ + +} + +void WayfireLockerApp::on_activate() +{ + WayfireShellApp::on_activate(); + auto debug = Glib::getenv("WF_LOCKER_DEBUG"); + if(debug == "1"){ + m_is_debug = true; + } + std::cout << "Locker activate" << std::endl; + lock = gtk_session_lock_instance_new(); + /* Session lock callbacks */ + g_signal_connect(lock, "locked", G_CALLBACK(on_session_locked_c), lock); + g_signal_connect(lock, "failed", G_CALLBACK(on_session_lock_failed_c), lock); + g_signal_connect(lock, "unlocked", G_CALLBACK(on_session_unlocked_c), lock); + g_signal_connect(lock, "monitor", G_CALLBACK(on_monitor_present_c), lock); + alternative_monitors = true; /* Don't use WayfireShellApp monitor tracking, we get a different set */ + new CssFromConfigString("locker/background_color", ".wf-locker {background-color:", ";}"); + new CssFromConfigFont("locker/clock_font", ".wf-locker .clock {", "}"); + new CssFromConfigFont("locker/pin_pad_font", ".wf-locker .pinpad-button {", "}"); + new CssFromConfigFont("locker/pin_reply_font", ".wf-locker .pinpad-current {", "}"); + new CssFromConfigFont("locker/fingerprint_font", ".wf-locker .fingerprint-text {", "}"); + new CssFromConfigFont("locker/battery_percent_font", ".wf-locker .battery-percent {", "}"); + new CssFromConfigFont("locker/battery_description_font", ".wf-locker .battery-description {", "}"); + new CssFromConfigFont("locker/instant_unlock_font", ".wf-locker .instant-unlock {", "}"); + new CssFromConfigInt("locker/battery_icon_size", ".wf-locker .battery-image {-gtk-icon-size:", "px;}"); + new CssFromConfigInt("locker/fingerprint_icon_size", ".wf-locker .fingerprint-icon {-gtk-icon-size:", "px;}"); + + /* Init plugins */ + plugins.emplace("clock", Plugin(new WayfireLockerClockPlugin())); + plugins.emplace("battery", Plugin(new WayfireLockerBatteryPlugin())); + plugins.emplace("password",Plugin(new WayfireLockerPasswordPlugin())); + plugins.emplace("instant",(Plugin(new WayfireLockerInstantPlugin()))); + plugins.emplace("pin",Plugin(new WayfireLockerPinPlugin())); + plugins.emplace("fingerprint", Plugin(new WayfireLockerFingerprintPlugin())); + + for(auto& it: plugins){ + if(it.second->should_enable()) + { + it.second->init(); + } + } + + if(is_debug()) + { + on_monitor_present(nullptr); + } else { + /* Demand the session be locked */ + gtk_session_lock_instance_lock(lock); + } +} + +/* A new monitor has been added to the lockscreen */ +void WayfireLockerApp::on_monitor_present(GdkMonitor* monitor) +{ + int id = window_id_count; + window_id_count ++; + /* Create lockscreen with a grid for contents */ + auto window = new Gtk::Window(); + window->add_css_class("wf-locker"); + auto grid = new Gtk::Grid(); + window->set_child(*grid); + grid->set_expand(true); + grid->set_column_homogeneous(true); + grid->set_row_homogeneous(true); + for(int x = 0; x < 3; x ++) + { + for(int y = 0; y < 3; y ++) + { + auto box = new Gtk::Box(); + if(x == 0) + { + box->set_halign(Gtk::Align::START); + } else if (x == 2) + { + box->set_halign(Gtk::Align::END); + } + if(y == 0) + { + box->set_valign(Gtk::Align::START); + } else if (y == 2) + { + box->set_valign(Gtk::Align::END); + } + box->set_orientation(Gtk::Orientation::VERTICAL); + grid->attach(*box, x, y); + } + } + for(auto& it: plugins){ + if(it.second->should_enable()) + { + it.second->add_output(id, grid); + } + } + window->signal_close_request().connect([this, id](){ + for(auto& it: plugins){ + it.second->remove_output(id); + } + return false; + },false); + if(is_debug()) + { + window->present(); + } else { + gtk_session_lock_instance_assign_window_to_monitor(lock, window->gobj(), monitor); + } +} + +/* Called on any successful auth to unlock & end locker */ +void WayfireLockerApp::unlock() +{ + if (is_debug()) + { + exit(0); + } + gtk_session_lock_instance_unlock(lock); +} + +void WayfireLockerApp::create(int argc, char **argv) +{ + if (instance) + { + throw std::logic_error("Running WayfireLockerApp twice!"); + } + + instance = std::unique_ptr(new WayfireLockerApp{}); + instance->run(argc, argv); +} + +/* Starting point */ +int main(int argc, char **argv) +{ + if(!gtk_session_lock_is_supported()) + { + std::cerr << "This session does not support locking" <bool{ + exit(0); + return 0; + },1); +} + +void on_monitor_present_c(GtkSessionLockInstance *lock, GdkMonitor *monitor, void *data) +{ + WayfireLockerApp::get().on_monitor_present(monitor); +} +/* Find user config */ +std::string WayfireLockerApp::get_config_file() +{ + if (cmdline_config.has_value()) + { + return cmdline_config.value(); + } + + std::string config_dir; + + char *config_home = getenv("XDG_CONFIG_HOME"); + if (config_home == NULL) + { + config_dir = std::string(getenv("HOME")) + "/.config"; + } else + { + config_dir = std::string(config_home); + } + + return config_dir + "/wf-shell.ini"; +} + +Plugin WayfireLockerApp::get_plugin(std::string name) +{ + if(plugins.find(name )==plugins.end()) + { + return nullptr; + } + return plugins.at(name); +} diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp new file mode 100644 index 00000000..a245f301 --- /dev/null +++ b/src/locker/locker.hpp @@ -0,0 +1,58 @@ +#ifndef WF_LOCKER_HPP +#define WF_LOCKER_HPP + +#include "plugin.hpp" +#include "wf-shell-app.hpp" +#include +#include +#include +#include +#include + +using Plugin = std::shared_ptr; +void on_session_locked_c(GtkSessionLockInstance *lock, void *data); +void on_session_lock_failed_c(GtkSessionLockInstance *lock, void *data); +void on_session_unlocked_c(GtkSessionLockInstance *lock, void *data); +void on_monitor_present_c(GtkSessionLockInstance *lock, GdkMonitor *monitor, void *data); + +class WayfireLockerApp : public WayfireShellApp +{ + private: + WayfireLockerApp(WayfireLockerApp const& copy); + WayfireLockerApp& operator=(WayfireLockerApp const& copy); + + std::string get_config_file() override; + + GtkSessionLockInstance *lock; + std::map plugins = {}; + + bool m_is_debug=false; + int window_id_count = 0; + + std::vector> css_rules; + + + public: + using WayfireShellApp::WayfireShellApp; + static void create(int argc, char **argv); + static WayfireLockerApp& get() + { + return (WayfireLockerApp&) WayfireShellApp::get(); + } + + /* Starts the program. get() is valid afterward the first (and the only) + * call to create() */ + void on_monitor_present(GdkMonitor* monitor); + void on_activate() override; + bool is_debug() { + return m_is_debug; + }; + ~WayfireLockerApp(); + + Plugin get_plugin(std::string name); + void unlock(); + + private: +}; + +#endif \ No newline at end of file diff --git a/src/locker/meson.build b/src/locker/meson.build new file mode 100644 index 00000000..f74f474b --- /dev/null +++ b/src/locker/meson.build @@ -0,0 +1,33 @@ +widget_sources = [ + 'plugin/clock.cpp', + 'plugin/battery.cpp', + 'plugin/password.cpp', + 'plugin/instant.cpp', + 'plugin/pin.cpp', + 'plugin/fingerprint.cpp' +] +deps = [ + gtklayershell, + gtkmm, + wayland_client, + libutil, + wf_protos, + wfconfig, + xkbregistry, + json, + pam, + openssl +] + +# We'll come back here with a 'mute mic' widget and a 'volume' widget +#if libpulse.found() +# widget_sources += 'widgets/volume.cpp' +# deps += [libpulse, libgvc] +#endif + +executable( + 'wf-locker', + ['locker.cpp'] + widget_sources, + dependencies: deps, + install: true, +) diff --git a/src/locker/plugin.hpp b/src/locker/plugin.hpp new file mode 100644 index 00000000..41629ba4 --- /dev/null +++ b/src/locker/plugin.hpp @@ -0,0 +1,63 @@ +#ifndef LOCKER_PLUGIN_HPP +#define LOCKER_PLUGIN_HPP + +#include +#include + +#define DEFAULT_PANEL_HEIGHT "48" +#define DEFAULT_ICON_SIZE 32 + +#define PANEL_POSITION_BOTTOM "bottom" +#define PANEL_POSITION_TOP "top" + +/* Differs to panel widgets. + One instance of each plugin exists and it must account for + multiple widgets in multiple windows. */ +class WayfireLockerPlugin +{ + public: + /* If true, plugin should be instantiated, init called, and used in lock screen + If false, plugin will be instantiated but never init'ed. + + We *do not* do config reloading. Sample config on construction or init, but not live */ + virtual bool should_enable() = 0; + virtual void add_output(int id, Gtk::Grid *grid) = 0; + virtual void remove_output(int id) = 0; + virtual void init() = 0; + virtual ~WayfireLockerPlugin() = default; + + /* Config string to box from grid */ + Gtk::Box* get_plugin_position(std::string pos_string, Gtk::Grid *grid){ + if (pos_string == "top-left") + { + return (Gtk::Box*)grid->get_child_at(0, 0); + } else if (pos_string == "top-center") + { + return (Gtk::Box*)grid->get_child_at(1, 0); + } else if (pos_string == "top-right") + { + return (Gtk::Box*)grid->get_child_at(2, 0); + } else if (pos_string == "center-left") + { + return (Gtk::Box*)grid->get_child_at(0, 1); + } else if (pos_string == "center-center") + { + return (Gtk::Box*)grid->get_child_at(1, 1); + } else if (pos_string == "center-right") + { + return (Gtk::Box*)grid->get_child_at(2, 1); + } else if (pos_string == "bottom-left") + { + return (Gtk::Box*)grid->get_child_at(0, 2); + } else if (pos_string == "bottom-center") + { + return (Gtk::Box*)grid->get_child_at(1, 2); + } else if (pos_string == "bottom-right") + { + return (Gtk::Box*)grid->get_child_at(2, 2); + } + return nullptr; + } +}; + +#endif \ No newline at end of file diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp new file mode 100644 index 00000000..93b4454f --- /dev/null +++ b/src/locker/plugin/battery.cpp @@ -0,0 +1,241 @@ +#include + +#include "gtkmm/image.h" +#include "gtkmm/label.h" +#include "gtkmm/box.h" +#include "wf-option-wrap.hpp" +#include +#include "battery.hpp" + + +static const std::string BATTERY_STATUS_ICON = "icon"; // icon +static const std::string BATTERY_STATUS_PERCENT = "percentage"; // icon + percentage +static const std::string BATTERY_STATUS_FULL = "full"; // icon + percentage + TimeToFull/TimeToEmpty + +static bool is_charging(uint32_t state) +{ + return (state == 1) || (state == 5); +} + +static bool is_discharging(uint32_t state) +{ + return (state == 2) || (state == 6); +} + +static std::string state_descriptions[] = { + "Unknown", // 0 + "Charging", // 1 + "Discharging", // 2 + "Empty", // 3 + "Fully charged", // 4 + "Pending charge", // 5 + "Pending discharge", // 6 +}; + +static std::string get_device_type_description(uint32_t type) +{ + if (type == 2) + { + return "Battery "; + } + + if (type == 3) + { + return "UPS "; + } + + return ""; +} + +static std::string format_digit(int digit) +{ + return digit <= 9 ? ("0" + std::to_string(digit)) : + std::to_string(digit); +} + +static std::string uint_to_time(int64_t time) +{ + int hrs = time / 3600; + int min = (time / 60) % 60; + + return format_digit(hrs) + ":" + format_digit(min); +} + + +bool WayfireLockerBatteryPlugin::should_enable() +{ + return (bool) enable; +} + +void WayfireLockerBatteryPlugin::update_percentages(std::string text) +{ + for (auto& it: labels) + { + it.second->set_label(text); + } +} + +void WayfireLockerBatteryPlugin::update_descriptions(std::string text) +{ + for (auto& it: subtexts) + { + it.second->set_label(text); + } +} + +void WayfireLockerBatteryPlugin::update_images() +{ + Glib::Variant icon_name; + display_device->get_cached_property(icon_name, ICON); + for (auto& it: images) + { + it.second->set_from_icon_name(icon_name.get()); + } +} + +void WayfireLockerBatteryPlugin::add_output(int id, Gtk::Grid *grid) +{ + Gtk::Grid *batt_grid = new Gtk::Grid(); + labels.emplace(id, std::shared_ptr(new Gtk::Label())); + subtexts.emplace(id, std::shared_ptr(new Gtk::Label())); + images.emplace(id, std::shared_ptr(new Gtk::Image())); + auto label = labels[id]; + auto subtext = subtexts[id]; + auto image = images[id]; + + label->add_css_class("battery-percent"); + subtext->add_css_class("battery-description"); + image->add_css_class("battery-image"); + + batt_grid->attach(*image, 0, 0); + batt_grid->attach(*label, 1, 0); + batt_grid->attach(*subtext, 0, 1,2,1); + + Gtk::Box* box = get_plugin_position(battery_position, grid); + + box->append(*batt_grid); + + update_details(); +} + +void WayfireLockerBatteryPlugin::remove_output(int id) +{ + labels.erase(id); +} + +void WayfireLockerBatteryPlugin::init() +{ + if (!setup_dbus()) + { + return; + } +} + + +bool WayfireLockerBatteryPlugin::setup_dbus() +{ + auto cancellable = Gio::Cancellable::create(); + connection = Gio::DBus::Connection::get_sync(Gio::DBus::BusType::SYSTEM, cancellable); + if (!connection) + { + std::cerr << "Failed to connect to dbus" << std::endl; + return false; + } + + upower_proxy = Gio::DBus::Proxy::create_sync(connection, UPOWER_NAME, + "/org/freedesktop/UPower", + "org.freedesktop.UPower"); + if (!upower_proxy) + { + std::cerr << "Failed to connect to UPower" << std::endl; + return false; + } + + display_device = Gio::DBus::Proxy::create_sync(connection, + UPOWER_NAME, + DISPLAY_DEVICE, + "org.freedesktop.UPower.Device"); + if (!display_device) + { + return false; + } + + Glib::Variant present; + display_device->get_cached_property(present, SHOULD_DISPLAY); + if (present.get()) + { + display_device->signal_properties_changed().connect( + sigc::mem_fun(*this, &WayfireLockerBatteryPlugin::on_properties_changed)); + + return true; + } + + return false; +} + +void WayfireLockerBatteryPlugin::on_properties_changed( + const Gio::DBus::Proxy::MapChangedProperties& properties, + const std::vector& invalidated) +{ + bool invalid_icon = false, invalid_details = false; + for (auto& prop : properties) + { + if (prop.first == ICON) + { + invalid_icon = true; + } + + if ((prop.first == TYPE) || (prop.first == STATE) || (prop.first == PERCENTAGE) || + (prop.first == TIMETOFULL) || (prop.first == TIMETOEMPTY)) + { + invalid_details = true; + } + + if (prop.first == SHOULD_DISPLAY) + { + } + } + + if (invalid_icon) + { + update_images(); + } + + if (invalid_details) + { + update_details(); + } +} + +void WayfireLockerBatteryPlugin::update_details() +{ + Glib::Variant type; + display_device->get_cached_property(type, TYPE); + + Glib::Variant vstate; + display_device->get_cached_property(vstate, STATE); + uint32_t state = vstate.get(); + + Glib::Variant vpercentage; + display_device->get_cached_property(vpercentage, PERCENTAGE); + auto percentage_string = std::to_string((int)vpercentage.get()) + "%"; + + Glib::Variant time_to_full; + display_device->get_cached_property(time_to_full, TIMETOFULL); + + Glib::Variant time_to_empty; + display_device->get_cached_property(time_to_empty, TIMETOEMPTY); + + std::string description = state_descriptions[state]; + if (is_charging(state)) + { + description += ", " + uint_to_time(time_to_full.get()) + " until full"; + } else if (is_discharging(state)) + { + description += ", " + uint_to_time(time_to_empty.get()) + " remaining"; + } + + update_descriptions(get_device_type_description(type.get()) + description); + update_percentages(percentage_string); + update_images(); +} diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp new file mode 100644 index 00000000..49ae24ae --- /dev/null +++ b/src/locker/plugin/battery.hpp @@ -0,0 +1,58 @@ +#ifndef LOCKER_BATTERY_PLUGIN_HPP +#define LOCKER_BATTERY_PLUGIN_HPP +#include +#include +#include + +#include +#include +#include +#include +#include "../plugin.hpp" +#include "../../util/wf-option-wrap.hpp" + +using DBusConnection = Glib::RefPtr; +using DBusProxy = Glib::RefPtr; +/* Shamelessly copied in from battery in panel */ + +#define UPOWER_NAME "org.freedesktop.UPower" +#define DISPLAY_DEVICE "/org/freedesktop/UPower/devices/DisplayDevice" + +#define ICON "IconName" +#define TYPE "Type" +#define STATE "State" +#define PERCENTAGE "Percentage" +#define TIMETOFULL "TimeToFull" +#define TIMETOEMPTY "TimeToEmpty" +#define SHOULD_DISPLAY "IsPresent" + +class WayfireLockerBatteryPlugin: public WayfireLockerPlugin{ + private: + DBusConnection connection; + DBusProxy upower_proxy, display_device; + void on_properties_changed( + const Gio::DBus::Proxy::MapChangedProperties& properties, + const std::vector& invalidated); + bool setup_dbus(); + + public: + WayfireLockerBatteryPlugin(){}; + void add_output(int id, Gtk::Grid *grid) override; + void remove_output(int id) override; + bool should_enable() override; + void init() override; + + WfOption battery_position{"locker/battery_position"}; + WfOption enable{"locker/battery_enable"}; + + void update_percentages(std::string text); + void update_descriptions(std::string text); + void update_images(); + void update_details(); + + std::unordered_map> images; + std::unordered_map> subtexts; + std::unordered_map> labels; +}; + +#endif \ No newline at end of file diff --git a/src/locker/plugin/clock.cpp b/src/locker/plugin/clock.cpp new file mode 100644 index 00000000..7432dadf --- /dev/null +++ b/src/locker/plugin/clock.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include "clock.hpp" + +bool WayfireLockerClockPlugin::should_enable() +{ + return (bool) enable; +} + +void WayfireLockerClockPlugin::update_labels(std::string text){ + for (auto& it: labels) + { + it.second->set_label(text); + } + label_contents = text; +} + +void WayfireLockerClockPlugin::add_output(int id, Gtk::Grid *grid) +{ + labels.emplace(id, std::shared_ptr(new Gtk::Label())); + auto label = labels[id]; + label->add_css_class("clock"); + label->set_label(label_contents); + + Gtk::Box* box = get_plugin_position(WfOption{"locker/clock_position"}, grid); +box->append(*label); +} + +void WayfireLockerClockPlugin::remove_output(int id) +{ + labels.erase(id); +} + +void WayfireLockerClockPlugin::update_time() +{ + auto time = Glib::DateTime::create_now_local(); + auto text = time.format((std::string)format); + + /* Sometimes GLib::DateTime will add leading spaces. This results in + * unevenly balanced padding around the text, which looks quite bad. + * + * This could be circumvented with the modifiers the user passes to the + * format string, * but to remove the requirement that the user does + * something fancy, we just remove any leading spaces. */ + int i = 0; + while (i < (int)text.length() && text[i] == ' ') + { + i++; + } + this->update_labels(text.substr(i)); +} + +WayfireLockerClockPlugin::WayfireLockerClockPlugin() +{ + +} + +void WayfireLockerClockPlugin::init() +{ + timeout = Glib::signal_timeout().connect_seconds( + [this](){ + this->update_time(); + return G_SOURCE_CONTINUE; + }, 1); +} \ No newline at end of file diff --git a/src/locker/plugin/clock.hpp b/src/locker/plugin/clock.hpp new file mode 100644 index 00000000..4874cd30 --- /dev/null +++ b/src/locker/plugin/clock.hpp @@ -0,0 +1,29 @@ +#ifndef LOCKER_CLOCK_PLUGIN_HPP +#define LOCKER_CLOCK_PLUGIN_HPP + +#include +#include + +#include "../plugin.hpp" +#include "../../util/wf-option-wrap.hpp" + +class WayfireLockerClockPlugin: public WayfireLockerPlugin{ + public: + WayfireLockerClockPlugin(); + void add_output(int id, Gtk::Grid *grid) override; + void remove_output(int id) override; + bool should_enable() override; + void init() override; + + WfOption enable{"locker/clock_enable"}; + WfOption format{"locker/clock_format"}; + + sigc::connection timeout; + void update_labels(std::string text); + void update_time(); + + std::unordered_map> labels; + std::string label_contents=""; +}; + +#endif \ No newline at end of file diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp new file mode 100644 index 00000000..5c134e2a --- /dev/null +++ b/src/locker/plugin/fingerprint.cpp @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../util/wf-option-wrap.hpp" +#include "glib.h" +#include "locker.hpp" +#include "fingerprint.hpp" + + +WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : + dbus_name_id(Gio::DBus::own_name(Gio::DBus::BusType::SYSTEM, + "net.reactivated.Fprint", + sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))) + {} + +WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() +{ + if (device_proxy) + { + device_proxy->call_sync("Release"); + } +} + +void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr & connection, const Glib::ustring & name) +{ + /* Bail here if config has this disabled */ + if (!enable) + { + return; + } + Gio::DBus::Proxy::create(connection, + "net.reactivated.Fprint", + "/net/reactivated/Fprint/Manager", + "net.reactivated.Fprint.Manager", + [this, connection] (const Glib::RefPtr & result) { + auto manager_proxy = Gio::DBus::Proxy::create_finish(result); + auto variant = manager_proxy->call_sync("GetDefaultDevice"); + Glib::Variant item_path; + variant.get_child(item_path,0); + Gio::DBus::Proxy::create(connection, + "net.reactivated.Fprint", + item_path.get(), + "net.reactivated.Fprint.Device", + sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_device_acquired) + ); + + } + ); +} + +void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr & result) +{ + device_proxy = Gio::DBus::Proxy::create_finish(result); + char* username = getlogin(); + update_labels("Listing fingers..."); + auto reply = device_proxy->call_sync("ListEnrolledFingers", nullptr, Glib::Variant>::create(username)); + if(reply.get_n_children()>0) + { + // User has at least one fingerprint on file! + update_labels("Fingerprint Ready"); + update_image("fingerprint"); + } else { + // Zero fingers for this user. + update_labels("No fingerprints enrolled"); + update_image("nofingerprint"); + } + Glib::Variant finger; + reply.get_child(finger, 0); + update_labels("Claiming device..."); + device_proxy->signal_signal().connect([this] (const Glib::ustring & sender_name, + const Glib::ustring & signal_name, + const Glib::VariantContainerBase & params){ + if (signal_name == "VerifyStatus") + { + Glib::Variant mesg; + Glib::Variant done; + params.get_child(mesg,0); + params.get_child(done, 1); + update_labels(mesg.get()); + if(mesg.get() == "verify-match") + { + WayfireLockerApp::get().unlock(); + } + if(mesg.get() == "verify-no-match") + { + /* Reschedule fingerprint scan */ + Glib::signal_timeout().connect_seconds( + [this](){ + this->start_fingerprint_scanning(); + return G_SOURCE_REMOVE; + }, 5); + update_image("nofingerprint"); + update_labels("Invalid fingerprint"); + } + if(done.get()){ + is_scanning=false; + device_proxy->call_sync("VerifyStop"); + } + } + },false); + device_proxy->call_sync("Claim", nullptr, Glib::Variant>::create({username})); + finger_name = finger.get(); + + /* Start fingerprint reader 5 seconds after start + This fixes an issue where the fingerprint reader + is a button which locks the screen */ + Glib::signal_timeout().connect_seconds( + [this](){ + this->start_fingerprint_scanning(); + return G_SOURCE_REMOVE; + }, 5); +} + +void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() +{ + if(device_proxy && !is_scanning) + { + update_labels("Use fingerprint to unlock"); + is_scanning=true; + device_proxy->call_sync("VerifyStart", + nullptr, + Glib::Variant>::create({finger_name}) + ); + } else + { + update_labels("Unable to start fingerprint scan"); + } +} + + + +void WayfireLockerFingerprintPlugin::init() +{ + WfOption enabled{"locker/fingerprint_enable"}; + enable=enabled; + + // If no device : set enable = false +} + + +void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid* grid) +{ + labels.emplace(id, std::shared_ptr(new Gtk::Label())); + images.emplace(id, std::shared_ptr(new Gtk::Image())); + + auto image = images[id]; + auto label = labels[id]; + + image->set_from_icon_name("fingerprint"); + label->set_label("No Fingerprint device found"); + + image->add_css_class("fingerprint-icon"); + label->add_css_class("fingerprint-text"); + + Gtk::Box* box = get_plugin_position(WfOption{"locker/fingerprint_position"}, grid); + box->append(*image); + + box->append(*label); +} + +void WayfireLockerFingerprintPlugin::remove_output(int id) +{ + labels.erase(id); + images.erase(id); +} + +bool WayfireLockerFingerprintPlugin::should_enable() +{ + return enable; +} + +void WayfireLockerFingerprintPlugin::update_image(std::string image) +{ + for (auto& it: images) + { + it.second->set_from_icon_name(image); + } + icon_contents = image; +} + +void WayfireLockerFingerprintPlugin::update_labels(std::string text) +{ + for (auto& it: labels) + { + it.second->set_label(text); + } + label_contents = text; +} \ No newline at end of file diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp new file mode 100644 index 00000000..47b59ffd --- /dev/null +++ b/src/locker/plugin/fingerprint.hpp @@ -0,0 +1,40 @@ +#ifndef LOCKER_FINGERPRINT_PLUGIN_HPP +#define LOCKER_FINGERPRINT_PLUGIN_HPP + +#include +#include +#include +#include + +#include "../plugin.hpp" +#include "giomm/dbusproxy.h" +#include "glibmm/refptr.h" + +class WayfireLockerFingerprintPlugin: public WayfireLockerPlugin{ + public: + guint dbus_name_id; + Glib::RefPtr device_proxy; + + WayfireLockerFingerprintPlugin(); + ~WayfireLockerFingerprintPlugin(); + void on_bus_acquired(const Glib::RefPtr & connection, const Glib::ustring & name); + void on_device_acquired(const Glib::RefPtr & result); + void start_fingerprint_scanning(); + void add_output(int id, Gtk::Grid *grid) override; + void remove_output(int id) override; + bool should_enable() override; + void init() override; + + bool enable; + bool is_scanning; + void update_labels(std::string text); + void update_image(std::string image); + + std::unordered_map> labels; + std::unordered_map> images; + std::string icon_contents=""; + std::string label_contents=""; + std::string finger_name=""; +}; + +#endif \ No newline at end of file diff --git a/src/locker/plugin/instant.cpp b/src/locker/plugin/instant.cpp new file mode 100644 index 00000000..563660ec --- /dev/null +++ b/src/locker/plugin/instant.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include "../locker.hpp" +#include "instant.hpp" + +bool WayfireLockerInstantPlugin::should_enable() +{ + return (bool) enable; +} + +void WayfireLockerInstantPlugin::add_output(int id, Gtk::Grid *grid) +{ + buttons.emplace(id, std::shared_ptr(new Gtk::Button())); + auto button = buttons[id]; + button->set_label("Press to unlock"); + button->add_css_class("instant-unlock"); + + Gtk::Box* box = get_plugin_position(WfOption{"locker/instant_unlock_position"}, grid); + box->append(*button); + + button->signal_clicked().connect([](){ + WayfireLockerApp::get().unlock(); + }, false); +} + +void WayfireLockerInstantPlugin::remove_output(int id) +{ + buttons.erase(id); +} + +void WayfireLockerInstantPlugin::init() +{ + +} \ No newline at end of file diff --git a/src/locker/plugin/instant.hpp b/src/locker/plugin/instant.hpp new file mode 100644 index 00000000..9b071a91 --- /dev/null +++ b/src/locker/plugin/instant.hpp @@ -0,0 +1,23 @@ +#ifndef LOCKER_INSTANT_PLUGIN_HPP +#define LOCKER_INSTANT_PLUGIN_HPP + +#include + +#include "../plugin.hpp" +#include "../../util/wf-option-wrap.hpp" + +class WayfireLockerInstantPlugin: public WayfireLockerPlugin{ + public: + WayfireLockerInstantPlugin(){}; + void add_output(int id, Gtk::Grid *grid) override; + void remove_output(int id) override; + bool should_enable() override; + void init() override; + + WfOption enable{"locker/instant_unlock_enable"}; + + std::unordered_map> buttons; + +}; + +#endif \ No newline at end of file diff --git a/src/locker/plugin/password.cpp b/src/locker/plugin/password.cpp new file mode 100644 index 00000000..1d73ab4e --- /dev/null +++ b/src/locker/plugin/password.cpp @@ -0,0 +1,147 @@ +#include +#include +#include "password.hpp" +#include "gtkmm/box.h" +#include "gtkmm/entry.h" +#include "gtkmm/label.h" +#include "locker.hpp" + +#include +#include +#include +#include + + +bool WayfireLockerPasswordPlugin::should_enable() +{ + return (bool) enable; +} + +void WayfireLockerPasswordPlugin::update_labels(std::string text){ + for (auto& it : labels) + { + it.second->set_label(text); + } + label_contents = text; +} + +void WayfireLockerPasswordPlugin::blank_passwords() +{ + for (auto& it : entries) + { + it.second->set_text(""); + } +} + +void WayfireLockerPasswordPlugin::add_output(int id, Gtk::Grid *grid) +{ + labels.emplace(id, std::shared_ptr(new Gtk::Label())); + entries.emplace(id, std::shared_ptr(new Gtk::Entry)); + auto label = labels[id]; + auto entry = entries[id]; + label->add_css_class("password-reply"); + entry->add_css_class("password-entry"); + entry->set_placeholder_text("Password"); + label->set_label(label_contents); + entry->set_visibility(false); + /* Set entry callback for return */ + entry->signal_activate().connect([this, entry](){ + auto password = entry->get_text(); + if(password.length() > 0 ) + { + submit_user_password(password); + } + },true); + /* Add to window */ + Gtk::Box* box = get_plugin_position(WfOption{"locker/password_position"}, grid); + box->append(*entry); + box->append(*label); +} + +void WayfireLockerPasswordPlugin::remove_output(int id) +{ + labels.erase(id); + entries.erase(id); +} + +WayfireLockerPasswordPlugin::WayfireLockerPasswordPlugin() +{ +} + +/* PAM password C code... */ +int pam_conversation(int num_mesg, const struct pam_message **mesg, struct pam_response **resp, void *appdata_ptr) +{ + std::cout << "PAM convo step ... " << std::endl; + + WayfireLockerPasswordPlugin* pass_plugin = (WayfireLockerPasswordPlugin*)appdata_ptr; + *resp = (struct pam_response*) calloc(num_mesg, sizeof(struct pam_response)); + if(*resp == NULL) + { + std::cerr << "PAM reply allocation failed" <msg << std::endl; + resp[count]->resp_retcode = 0; + /* Echo OFF prompt should be user password. */ + if (mesg[count]->msg_style == PAM_PROMPT_ECHO_OFF) + { + resp[count]->resp = strdup(pass_plugin->submitted_password.c_str()); + + } else if (mesg[count]->msg_style == PAM_ERROR_MSG) { + pass_plugin->update_labels(mesg[count]->msg); + } else if (mesg[count]->msg_style == PAM_TEXT_INFO) { + pass_plugin->update_labels(mesg[count]->msg); + } + } + return PAM_SUCCESS; +} + +void WayfireLockerPasswordPlugin::submit_user_password(std::string password) +{ + submitted_password = password; + blank_passwords(); + std::cout << "Unlocking ... " << std::endl; + /* Get username*/ + char* username = getlogin(); + /* Init PAM conversation */ + const struct pam_conv local_conversation = { pam_conversation, this}; + pam_handle_t *local_auth_handle = NULL; // this gets set by pam_start + int retval; + /* Start the password-based conversation */ + std::cout << "PAM start ... " << std::endl; + retval = pam_start("wf-locker-password", username, &local_conversation, &local_auth_handle); + if (retval != PAM_SUCCESS) + { + /* We don't expect to be here. No graceful way out of this. */ + std::cout << "PAM start returned " << retval << std::endl; + update_labels("pam_start failure"); + exit(retval); + } + std::cout << "PAM auth ... " << std::endl; + /* Request authenticate */ + retval = pam_authenticate(local_auth_handle, 0); + bool unlock = false; + if (retval != PAM_SUCCESS) + { + if (retval == PAM_AUTH_ERR) + { + std::cout << "Authentication failure." << std::endl; + update_labels("Authentication failure."); + } + } else { + std::cout << "Authenticate success." << std::endl; + unlock = true; + } + retval = pam_end(local_auth_handle, retval); + if (unlock) + { + WayfireLockerApp::get().unlock(); + } +} + +void WayfireLockerPasswordPlugin::init() +{ + +} \ No newline at end of file diff --git a/src/locker/plugin/password.hpp b/src/locker/plugin/password.hpp new file mode 100644 index 00000000..77b7f016 --- /dev/null +++ b/src/locker/plugin/password.hpp @@ -0,0 +1,33 @@ +#ifndef LOCKER_PASSWORD_PLUGIN_HPP +#define LOCKER_PASSWORD_PLUGIN_HPP + +#include +#include +#include +#include "../plugin.hpp" +#include "../../util/wf-option-wrap.hpp" + +int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); + +class WayfireLockerPasswordPlugin: public WayfireLockerPlugin{ + public: + WayfireLockerPasswordPlugin(); + void add_output(int id, Gtk::Grid *grid) override; + void remove_output(int id) override; + bool should_enable() override; + void init() override; + void submit_user_password(std::string password); + void blank_passwords(); + + WfOption enable{"locker/password_enable"}; + + sigc::connection timeout; + void update_labels(std::string text); + + std::unordered_map> labels; + std::unordered_map> entries; + std::string label_contents=""; + std::string submitted_password = ""; +}; + +#endif \ No newline at end of file diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp new file mode 100644 index 00000000..2a21403f --- /dev/null +++ b/src/locker/plugin/pin.cpp @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../util/wf-option-wrap.hpp" +#include "locker.hpp" +#include "pin.hpp" + + +/* + To set the PIN Hash required to enable this plugin, try running + `echo -n "1234" | sha512sum | head -c 128 > ~/.config/wf-locker.hash` + + Replace the numbers inside the echo quote. There must be one or more digits, + and any non-digit will render it impossible to unlock. + */ + +PinPad::PinPad() +{ + for (int count = 0; count < 10; count ++) + { + std::string number = std::to_string(count); + numbers[count].add_css_class("pinpad-number"); + numbers[count].add_css_class("pinpad-button"); + numbers[count].set_label(number); + numbers[count].signal_clicked().connect( + [number] () { + auto plugin = WayfireLockerApp::get().get_plugin("pin"); + auto plugin_cast = std::dynamic_pointer_cast(plugin); + plugin_cast->add_digit(number); + } + ); + } + bsub.set_label("✔️"); + bcan.set_label("❌"); + bsub.add_css_class("pinpad-submit"); + bsub.add_css_class("pinpad-button"); + bcan.add_css_class("pinpad-cancel"); + bcan.add_css_class("pinpad-button"); + bcan.signal_clicked().connect( + []() { + auto plugin = WayfireLockerApp::get().get_plugin("pin"); + auto plugin_cast = std::dynamic_pointer_cast(plugin); + plugin_cast->reset_pin(); + } + ); + bsub.signal_clicked().connect( + [] () { + auto plugin = WayfireLockerApp::get().get_plugin("pin"); + auto plugin_cast = std::dynamic_pointer_cast(plugin); + plugin_cast->submit_pin(); + } + ); + label.add_css_class("pinpad-current"); +} + +PinPad::~PinPad() +{ +} + +void PinPad::init() +{ + attach(label, 0, 0, 3); + attach(numbers[1],0,1); + attach(numbers[2], 1,1); + attach(numbers[3], 2, 1); + attach(numbers[4],0,2); + attach(numbers[5], 1,2); + attach(numbers[6], 2, 2); + attach(numbers[7],0,3); + attach(numbers[8], 1,3); + attach(numbers[9], 2, 3); + attach(bsub, 2, 4); + attach(numbers[0],1, 4); + attach(bcan, 0, 4); + set_vexpand(true); + set_column_homogeneous(true); + set_row_homogeneous(true); +} + +WayfireLockerPinPlugin::WayfireLockerPinPlugin() +{ + WfOption enabled{"locker/pin_enable"}; + enable = enabled; + if(!enable) + { + return; + } + + /* TODO ... */ + //if (cmdline_config.has_value()) + //{ + // return cmdline_config.value(); + //} + std::string config_dir; + + char *config_home = getenv("XDG_CONFIG_HOME"); + if (config_home == NULL) + { + config_dir = std::string(getenv("HOME")) + "/.config"; + } else + { + config_dir = std::string(config_home); + } + + std::ifstream f(config_dir + "/wf-locker.hash"); + if(!f.is_open()){ + std::cerr << "No PIN hash set" << std::endl; + enable = false; + return; + } + + std::string s; + if(!getline(f,s)){ + std::cerr << "No PIN hash set" << std::endl; + enable = false; + return; + } + if(s.length() != 128){ + std::cerr << "Invalid PIN hash" << std::endl; + enable= false; + return; + } + pinhash = s; +} + +void WayfireLockerPinPlugin::init() +{ +} + +bool WayfireLockerPinPlugin::should_enable() +{ + return enable; +} + +void WayfireLockerPinPlugin::add_output(int id, Gtk::Grid *grid) +{ + pinpads.emplace(id, new PinPad()); + auto pinpad = pinpads[id]; + pinpad->add_css_class("pinpad"); + pinpad->init(); + Gtk::Box* box = get_plugin_position(WfOption{"locker/pin_position"}, grid); + box->append(*pinpad); + update_labels(); /* Update all to set this one? maybe overkill */ +} + +void WayfireLockerPinPlugin::remove_output(int id) +{ + pinpads.erase(id); +} + +void WayfireLockerPinPlugin::add_digit(std::string digit) +{ + pin = pin + digit; + update_labels(); +} + +void WayfireLockerPinPlugin::reset_pin() +{ + pin = ""; + update_labels(); +} + +void WayfireLockerPinPlugin::update_labels() +{ + std::string asterisks(pin.length(), '*'); + for(auto& it: pinpads) + { + it.second->label.set_label(asterisks); + } +} + +void WayfireLockerPinPlugin::submit_pin() +{ + auto hash = sha512(pin); + if (hash == pinhash) + { + WayfireLockerApp::get().unlock(); + } + pin = ""; + update_labels(); +} + +std::string WayfireLockerPinPlugin::sha512(const std::string input) +{ + unsigned char hash[EVP_MAX_MD_SIZE]; + unsigned int hash_length = 0; + EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + EVP_DigestInit(mdctx, EVP_sha512()); + EVP_DigestUpdate(mdctx, input.c_str(), input.size()); + EVP_DigestFinal(mdctx, hash, &hash_length); + EVP_MD_CTX_free(mdctx); + + std::stringstream ss; + + for(int i = 0; i < SHA512_DIGEST_LENGTH; i++){ + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast( hash[i] ); + } + return ss.str(); +} \ No newline at end of file diff --git a/src/locker/plugin/pin.hpp b/src/locker/plugin/pin.hpp new file mode 100644 index 00000000..bfa2c018 --- /dev/null +++ b/src/locker/plugin/pin.hpp @@ -0,0 +1,48 @@ +#ifndef LOCKER_PIN_PLUGIN_HPP +#define LOCKER_PIN_PLUGIN_HPP + +#include +#include +#include +#include + +#include "../plugin.hpp" +#include "glibmm/refptr.h" + +/* Rather than keep an unordered list for each widget, put them together */ +class WayfireLockerPinPlugin; +class PinPad : public Gtk::Grid{ + public: + PinPad(); + ~PinPad(); + Gtk::Button bsub, bcan; + Gtk::Label label; + void init(); + void check(); + Gtk::Button numbers[10]; + +}; + +class WayfireLockerPinPlugin: public WayfireLockerPlugin{ + public: + WayfireLockerPinPlugin(); + void add_output(int id, Gtk::Grid *grid) override; + void remove_output(int id) override; + bool should_enable() override; + void init() override; + + void update_labels(); + void submit_pin(); + void reset_pin(); + void add_digit(std::string digit); + std::string sha512(const std::string input); + + bool enable= false; + + std::unordered_map> pinpads; + + std::string pin=""; + std::string pinhash="nope"; +}; + +#endif \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index e8931648..118bdec5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -2,6 +2,7 @@ subdir('util') subdir('panel') subdir('background') subdir('dock') +subdir('locker') pkgconfig = import('pkgconfig') pkgconfig.generate( diff --git a/src/util/css-config.cpp b/src/util/css-config.cpp index a2138453..5468cf23 100644 --- a/src/util/css-config.cpp +++ b/src/util/css-config.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/src/util/css-config.hpp b/src/util/css-config.hpp index bfd83f04..fd3b959a 100644 --- a/src/util/css-config.hpp +++ b/src/util/css-config.hpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include "wf-option-wrap.hpp" class CssFromConfig { diff --git a/src/util/wf-shell-app.cpp b/src/util/wf-shell-app.cpp index b740d864..31c7c927 100644 --- a/src/util/wf-shell-app.cpp +++ b/src/util/wf-shell-app.cpp @@ -222,17 +222,21 @@ void WayfireShellApp::on_activate() sigc::bind<0>(&handle_css_inotify_event, this), inotify_css_fd, Glib::IOCondition::IO_IN | Glib::IOCondition::IO_HUP); - // Hook up monitor tracking - auto display = Gdk::Display::get_default(); - auto monitors = display->get_monitors(); - monitors->signal_items_changed().connect(sigc::mem_fun(*this, &WayfireShellApp::output_list_updated)); - - // initial monitors - int num_monitors = monitors->get_n_items(); - for (int i = 0; i < num_monitors; i++) + if (!alternative_monitors) { - auto obj = std::dynamic_pointer_cast(monitors->get_object(i)); - add_output(obj); + + // Hook up monitor tracking + auto display = Gdk::Display::get_default(); + auto monitors = display->get_monitors(); + monitors->signal_items_changed().connect(sigc::mem_fun(*this, &WayfireShellApp::output_list_updated)); + + // initial monitors + int num_monitors = monitors->get_n_items(); + for (int i = 0; i < num_monitors; i++) + { + auto obj = std::dynamic_pointer_cast(monitors->get_object(i)); + add_output(obj); + } } } diff --git a/src/util/wf-shell-app.hpp b/src/util/wf-shell-app.hpp index c7036ba8..fc43f890 100644 --- a/src/util/wf-shell-app.hpp +++ b/src/util/wf-shell-app.hpp @@ -43,6 +43,7 @@ class WayfireShellApp protected: /** This should be initialized by the subclass in each program which uses * wf-shell-app */ + bool alternative_monitors = false; /* Used to skip monitor management in lockscreen */ static std::unique_ptr instance; std::optional cmdline_config; std::optional cmdline_css; diff --git a/subprojects/.wraplock b/subprojects/.wraplock new file mode 100644 index 00000000..e69de29b From b0b558185b1600bc08d0e13e33fdd9f8be8c5663 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 17:47:39 +0000 Subject: [PATCH 02/35] - try adding pam details --- data/meson.build | 2 ++ data/wf-locker-password | 1 + 2 files changed, 3 insertions(+) create mode 100644 data/wf-locker-password diff --git a/data/meson.build b/data/meson.build index a06c63fb..1880bc06 100644 --- a/data/meson.build +++ b/data/meson.build @@ -12,4 +12,6 @@ install_data(join_paths('icons', '256x256', 'wayfire.png'), install_dir: join_pa install_data(join_paths('icons', '512x512', 'wayfire.png'), install_dir: join_paths(get_option('prefix'), 'share', 'icons', 'hicolor', '512x512', 'apps')) install_data(join_paths('icons', 'scalable', 'wayfire.svg'), install_dir: join_paths(get_option('prefix'), 'share', 'icons', 'hicolor', 'scalable', 'apps')) +install_data('wf-locker-password', install_dir:'/etc/pam.d/') + subdir('css') \ No newline at end of file diff --git a/data/wf-locker-password b/data/wf-locker-password new file mode 100644 index 00000000..c1355e38 --- /dev/null +++ b/data/wf-locker-password @@ -0,0 +1 @@ +auth include login From e92f98425d24244900b655fb6db15a2caef330f7 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 17:49:36 +0000 Subject: [PATCH 03/35] - attempt to fix CI --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a1b316df..c3e4c8b8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,7 +9,7 @@ jobs: steps: - run: echo 'http://dl-cdn.alpinelinux.org/alpine/v3.22/community' > /etc/apk/repositories - run: echo 'http://dl-cdn.alpinelinux.org/alpine/v3.22/main' >> /etc/apk/repositories - - run: apk --no-cache add git g++ binutils pkgconf meson ninja musl-dev gtkmm4-dev vala gobject-introspection gobject-introspection-dev pulseaudio-dev libdbusmenu-glib-dev alsa-lib-dev yyjson-dev + - run: apk --no-cache add git g++ binutils pkgconf meson ninja musl-dev gtkmm4-dev vala gobject-introspection gobject-introspection-dev pulseaudio-dev libdbusmenu-glib-dev alsa-lib-dev yyjson-dev linux-pam-dev util-linux-login - run: echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories - run: echo 'http://dl-cdn.alpinelinux.org/alpine/edge/main' >> /etc/apk/repositories - run: apk --no-cache add wayland-protocols wayfire-dev gtk4-layer-shell-dev gtk4-layer-shell From 7b99566ac7d47483252c04913b4fb6f0dbc18bcd Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 17:52:00 +0000 Subject: [PATCH 04/35] - more --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c3e4c8b8..f828251c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,7 +9,7 @@ jobs: steps: - run: echo 'http://dl-cdn.alpinelinux.org/alpine/v3.22/community' > /etc/apk/repositories - run: echo 'http://dl-cdn.alpinelinux.org/alpine/v3.22/main' >> /etc/apk/repositories - - run: apk --no-cache add git g++ binutils pkgconf meson ninja musl-dev gtkmm4-dev vala gobject-introspection gobject-introspection-dev pulseaudio-dev libdbusmenu-glib-dev alsa-lib-dev yyjson-dev linux-pam-dev util-linux-login + - run: apk --no-cache add git g++ binutils pkgconf meson ninja musl-dev gtkmm4-dev vala gobject-introspection gobject-introspection-dev pulseaudio-dev libdbusmenu-glib-dev alsa-lib-dev yyjson-dev linux-pam-dev util-linux-login openssl-dev - run: echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories - run: echo 'http://dl-cdn.alpinelinux.org/alpine/edge/main' >> /etc/apk/repositories - run: apk --no-cache add wayland-protocols wayfire-dev gtk4-layer-shell-dev gtk4-layer-shell From a17d6d0604484bb47e6b9caf6a460c7eb1955a99 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 18:11:06 +0000 Subject: [PATCH 05/35] - first uncrustify --- src/locker/locker.cpp | 82 +++++++++------ src/locker/locker.hpp | 21 ++-- src/locker/plugin.hpp | 74 +++++++------- src/locker/plugin/battery.cpp | 23 ++--- src/locker/plugin/battery.hpp | 12 ++- src/locker/plugin/clock.cpp | 28 ++--- src/locker/plugin/clock.hpp | 11 +- src/locker/plugin/fingerprint.cpp | 113 ++++++++++---------- src/locker/plugin/fingerprint.hpp | 13 +-- src/locker/plugin/instant.cpp | 11 +- src/locker/plugin/instant.hpp | 13 +-- src/locker/plugin/password.cpp | 165 ++++++++++++++++-------------- src/locker/plugin/password.hpp | 12 ++- src/locker/plugin/pin.cpp | 109 +++++++++++--------- src/locker/plugin/pin.hpp | 19 ++-- 15 files changed, 378 insertions(+), 328 deletions(-) diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 706b3914..7b51ce96 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -25,17 +25,18 @@ #include "wf-shell-app.hpp" #include -WayfireLockerApp::~WayfireLockerApp(){ - -} +WayfireLockerApp::~WayfireLockerApp() +{} void WayfireLockerApp::on_activate() { WayfireShellApp::on_activate(); auto debug = Glib::getenv("WF_LOCKER_DEBUG"); - if(debug == "1"){ + if (debug == "1") + { m_is_debug = true; } + std::cout << "Locker activate" << std::endl; lock = gtk_session_lock_instance_new(); /* Session lock callbacks */ @@ -53,37 +54,40 @@ void WayfireLockerApp::on_activate() new CssFromConfigFont("locker/battery_description_font", ".wf-locker .battery-description {", "}"); new CssFromConfigFont("locker/instant_unlock_font", ".wf-locker .instant-unlock {", "}"); new CssFromConfigInt("locker/battery_icon_size", ".wf-locker .battery-image {-gtk-icon-size:", "px;}"); - new CssFromConfigInt("locker/fingerprint_icon_size", ".wf-locker .fingerprint-icon {-gtk-icon-size:", "px;}"); + new CssFromConfigInt("locker/fingerprint_icon_size", ".wf-locker .fingerprint-icon {-gtk-icon-size:", + "px;}"); /* Init plugins */ plugins.emplace("clock", Plugin(new WayfireLockerClockPlugin())); plugins.emplace("battery", Plugin(new WayfireLockerBatteryPlugin())); - plugins.emplace("password",Plugin(new WayfireLockerPasswordPlugin())); - plugins.emplace("instant",(Plugin(new WayfireLockerInstantPlugin()))); - plugins.emplace("pin",Plugin(new WayfireLockerPinPlugin())); + plugins.emplace("password", Plugin(new WayfireLockerPasswordPlugin())); + plugins.emplace("instant", (Plugin(new WayfireLockerInstantPlugin()))); + plugins.emplace("pin", Plugin(new WayfireLockerPinPlugin())); plugins.emplace("fingerprint", Plugin(new WayfireLockerFingerprintPlugin())); - for(auto& it: plugins){ - if(it.second->should_enable()) + for (auto& it : plugins) + { + if (it.second->should_enable()) { it.second->init(); } } - if(is_debug()) + if (is_debug()) { on_monitor_present(nullptr); - } else { + } else + { /* Demand the session be locked */ gtk_session_lock_instance_lock(lock); } } /* A new monitor has been added to the lockscreen */ -void WayfireLockerApp::on_monitor_present(GdkMonitor* monitor) +void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) { int id = window_id_count; - window_id_count ++; + window_id_count++; /* Create lockscreen with a grid for contents */ auto window = new Gtk::Window(); window->add_css_class("wf-locker"); @@ -92,45 +96,54 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor* monitor) grid->set_expand(true); grid->set_column_homogeneous(true); grid->set_row_homogeneous(true); - for(int x = 0; x < 3; x ++) + for (int x = 0; x < 3; x++) { - for(int y = 0; y < 3; y ++) + for (int y = 0; y < 3; y++) { auto box = new Gtk::Box(); - if(x == 0) + if (x == 0) { box->set_halign(Gtk::Align::START); } else if (x == 2) { box->set_halign(Gtk::Align::END); } - if(y == 0) + + if (y == 0) { box->set_valign(Gtk::Align::START); } else if (y == 2) { box->set_valign(Gtk::Align::END); } + box->set_orientation(Gtk::Orientation::VERTICAL); grid->attach(*box, x, y); } } - for(auto& it: plugins){ - if(it.second->should_enable()) + + for (auto& it : plugins) + { + if (it.second->should_enable()) { it.second->add_output(id, grid); } } - window->signal_close_request().connect([this, id](){ - for(auto& it: plugins){ + + window->signal_close_request().connect([this, id] () + { + for (auto& it : plugins) + { it.second->remove_output(id); } + return false; - },false); - if(is_debug()) + }, false); + if (is_debug()) { window->present(); - } else { + } else + { gtk_session_lock_instance_assign_window_to_monitor(lock, window->gobj(), monitor); } } @@ -142,6 +155,7 @@ void WayfireLockerApp::unlock() { exit(0); } + gtk_session_lock_instance_unlock(lock); } @@ -159,10 +173,11 @@ void WayfireLockerApp::create(int argc, char **argv) /* Starting point */ int main(int argc, char **argv) { - if(!gtk_session_lock_is_supported()) + if (!gtk_session_lock_is_supported()) { - std::cerr << "This session does not support locking" <bool{ + Glib::signal_timeout().connect_seconds([] () -> bool + { exit(0); return 0; - },1); + }, 1); } void on_monitor_present_c(GtkSessionLockInstance *lock, GdkMonitor *monitor, void *data) { WayfireLockerApp::get().on_monitor_present(monitor); } + /* Find user config */ std::string WayfireLockerApp::get_config_file() { @@ -212,15 +229,16 @@ std::string WayfireLockerApp::get_config_file() { config_dir = std::string(config_home); } - + return config_dir + "/wf-shell.ini"; } Plugin WayfireLockerApp::get_plugin(std::string name) { - if(plugins.find(name )==plugins.end()) + if (plugins.find(name) == plugins.end()) { return nullptr; } + return plugins.at(name); } diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index a245f301..e5a4e375 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -19,40 +19,41 @@ class WayfireLockerApp : public WayfireShellApp { private: WayfireLockerApp(WayfireLockerApp const& copy); - WayfireLockerApp& operator=(WayfireLockerApp const& copy); + WayfireLockerApp& operator =(WayfireLockerApp const& copy); std::string get_config_file() override; GtkSessionLockInstance *lock; std::map plugins = {}; - bool m_is_debug=false; + bool m_is_debug = false; int window_id_count = 0; std::vector> css_rules; - public: using WayfireShellApp::WayfireShellApp; static void create(int argc, char **argv); static WayfireLockerApp& get() { - return (WayfireLockerApp&) WayfireShellApp::get(); + return (WayfireLockerApp&)WayfireShellApp::get(); } /* Starts the program. get() is valid afterward the first (and the only) * call to create() */ - void on_monitor_present(GdkMonitor* monitor); + void on_monitor_present(GdkMonitor *monitor); void on_activate() override; - bool is_debug() { - return m_is_debug; - }; + bool is_debug() + { + return m_is_debug; + } + ~WayfireLockerApp(); Plugin get_plugin(std::string name); void unlock(); - + private: }; -#endif \ No newline at end of file +#endif diff --git a/src/locker/plugin.hpp b/src/locker/plugin.hpp index 41629ba4..3419a1a8 100644 --- a/src/locker/plugin.hpp +++ b/src/locker/plugin.hpp @@ -11,15 +11,15 @@ #define PANEL_POSITION_TOP "top" /* Differs to panel widgets. - One instance of each plugin exists and it must account for - multiple widgets in multiple windows. */ + * One instance of each plugin exists and it must account for + * multiple widgets in multiple windows. */ class WayfireLockerPlugin { public: /* If true, plugin should be instantiated, init called, and used in lock screen - If false, plugin will be instantiated but never init'ed. - - We *do not* do config reloading. Sample config on construction or init, but not live */ + * If false, plugin will be instantiated but never init'ed. + * + * We *do not* do config reloading. Sample config on construction or init, but not live */ virtual bool should_enable() = 0; virtual void add_output(int id, Gtk::Grid *grid) = 0; virtual void remove_output(int id) = 0; @@ -27,37 +27,39 @@ class WayfireLockerPlugin virtual ~WayfireLockerPlugin() = default; /* Config string to box from grid */ - Gtk::Box* get_plugin_position(std::string pos_string, Gtk::Grid *grid){ - if (pos_string == "top-left") - { - return (Gtk::Box*)grid->get_child_at(0, 0); - } else if (pos_string == "top-center") - { - return (Gtk::Box*)grid->get_child_at(1, 0); - } else if (pos_string == "top-right") - { - return (Gtk::Box*)grid->get_child_at(2, 0); - } else if (pos_string == "center-left") - { - return (Gtk::Box*)grid->get_child_at(0, 1); - } else if (pos_string == "center-center") - { - return (Gtk::Box*)grid->get_child_at(1, 1); - } else if (pos_string == "center-right") - { - return (Gtk::Box*)grid->get_child_at(2, 1); - } else if (pos_string == "bottom-left") - { - return (Gtk::Box*)grid->get_child_at(0, 2); - } else if (pos_string == "bottom-center") - { - return (Gtk::Box*)grid->get_child_at(1, 2); - } else if (pos_string == "bottom-right") - { - return (Gtk::Box*)grid->get_child_at(2, 2); - } - return nullptr; + Gtk::Box *get_plugin_position(std::string pos_string, Gtk::Grid *grid) + { + if (pos_string == "top-left") + { + return (Gtk::Box*)grid->get_child_at(0, 0); + } else if (pos_string == "top-center") + { + return (Gtk::Box*)grid->get_child_at(1, 0); + } else if (pos_string == "top-right") + { + return (Gtk::Box*)grid->get_child_at(2, 0); + } else if (pos_string == "center-left") + { + return (Gtk::Box*)grid->get_child_at(0, 1); + } else if (pos_string == "center-center") + { + return (Gtk::Box*)grid->get_child_at(1, 1); + } else if (pos_string == "center-right") + { + return (Gtk::Box*)grid->get_child_at(2, 1); + } else if (pos_string == "bottom-left") + { + return (Gtk::Box*)grid->get_child_at(0, 2); + } else if (pos_string == "bottom-center") + { + return (Gtk::Box*)grid->get_child_at(1, 2); + } else if (pos_string == "bottom-right") + { + return (Gtk::Box*)grid->get_child_at(2, 2); + } + + return nullptr; } }; -#endif \ No newline at end of file +#endif diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index 93b4454f..7cf9972a 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -61,15 +61,14 @@ static std::string uint_to_time(int64_t time) return format_digit(hrs) + ":" + format_digit(min); } - bool WayfireLockerBatteryPlugin::should_enable() { - return (bool) enable; + return (bool)enable; } void WayfireLockerBatteryPlugin::update_percentages(std::string text) { - for (auto& it: labels) + for (auto& it : labels) { it.second->set_label(text); } @@ -77,7 +76,7 @@ void WayfireLockerBatteryPlugin::update_percentages(std::string text) void WayfireLockerBatteryPlugin::update_descriptions(std::string text) { - for (auto& it: subtexts) + for (auto& it : subtexts) { it.second->set_label(text); } @@ -87,7 +86,7 @@ void WayfireLockerBatteryPlugin::update_images() { Glib::Variant icon_name; display_device->get_cached_property(icon_name, ICON); - for (auto& it: images) + for (auto& it : images) { it.second->set_from_icon_name(icon_name.get()); } @@ -99,9 +98,9 @@ void WayfireLockerBatteryPlugin::add_output(int id, Gtk::Grid *grid) labels.emplace(id, std::shared_ptr(new Gtk::Label())); subtexts.emplace(id, std::shared_ptr(new Gtk::Label())); images.emplace(id, std::shared_ptr(new Gtk::Image())); - auto label = labels[id]; + auto label = labels[id]; auto subtext = subtexts[id]; - auto image = images[id]; + auto image = images[id]; label->add_css_class("battery-percent"); subtext->add_css_class("battery-description"); @@ -109,10 +108,10 @@ void WayfireLockerBatteryPlugin::add_output(int id, Gtk::Grid *grid) batt_grid->attach(*image, 0, 0); batt_grid->attach(*label, 1, 0); - batt_grid->attach(*subtext, 0, 1,2,1); + batt_grid->attach(*subtext, 0, 1, 2, 1); + + Gtk::Box *box = get_plugin_position(battery_position, grid); - Gtk::Box* box = get_plugin_position(battery_position, grid); - box->append(*batt_grid); update_details(); @@ -131,7 +130,6 @@ void WayfireLockerBatteryPlugin::init() } } - bool WayfireLockerBatteryPlugin::setup_dbus() { auto cancellable = Gio::Cancellable::create(); @@ -192,8 +190,7 @@ void WayfireLockerBatteryPlugin::on_properties_changed( } if (prop.first == SHOULD_DISPLAY) - { - } + {} } if (invalid_icon) diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index 49ae24ae..d7598805 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -26,8 +26,9 @@ using DBusProxy = Glib::RefPtr; #define TIMETOEMPTY "TimeToEmpty" #define SHOULD_DISPLAY "IsPresent" -class WayfireLockerBatteryPlugin: public WayfireLockerPlugin{ - private: +class WayfireLockerBatteryPlugin : public WayfireLockerPlugin +{ + private: DBusConnection connection; DBusProxy upower_proxy, display_device; void on_properties_changed( @@ -35,8 +36,9 @@ class WayfireLockerBatteryPlugin: public WayfireLockerPlugin{ const std::vector& invalidated); bool setup_dbus(); - public: - WayfireLockerBatteryPlugin(){}; + public: + WayfireLockerBatteryPlugin() + {} void add_output(int id, Gtk::Grid *grid) override; void remove_output(int id) override; bool should_enable() override; @@ -55,4 +57,4 @@ class WayfireLockerBatteryPlugin: public WayfireLockerPlugin{ std::unordered_map> labels; }; -#endif \ No newline at end of file +#endif diff --git a/src/locker/plugin/clock.cpp b/src/locker/plugin/clock.cpp index 7432dadf..87d25576 100644 --- a/src/locker/plugin/clock.cpp +++ b/src/locker/plugin/clock.cpp @@ -5,14 +5,16 @@ bool WayfireLockerClockPlugin::should_enable() { - return (bool) enable; + return (bool)enable; } -void WayfireLockerClockPlugin::update_labels(std::string text){ - for (auto& it: labels) +void WayfireLockerClockPlugin::update_labels(std::string text) +{ + for (auto& it : labels) { it.second->set_label(text); } + label_contents = text; } @@ -23,8 +25,8 @@ void WayfireLockerClockPlugin::add_output(int id, Gtk::Grid *grid) label->add_css_class("clock"); label->set_label(label_contents); - Gtk::Box* box = get_plugin_position(WfOption{"locker/clock_position"}, grid); -box->append(*label); + Gtk::Box *box = get_plugin_position(WfOption{"locker/clock_position"}, grid); + box->append(*label); } void WayfireLockerClockPlugin::remove_output(int id) @@ -48,19 +50,19 @@ void WayfireLockerClockPlugin::update_time() { i++; } + this->update_labels(text.substr(i)); } WayfireLockerClockPlugin::WayfireLockerClockPlugin() -{ - -} +{} void WayfireLockerClockPlugin::init() { timeout = Glib::signal_timeout().connect_seconds( - [this](){ - this->update_time(); - return G_SOURCE_CONTINUE; - }, 1); -} \ No newline at end of file + [this] () + { + this->update_time(); + return G_SOURCE_CONTINUE; + }, 1); +} diff --git a/src/locker/plugin/clock.hpp b/src/locker/plugin/clock.hpp index 4874cd30..72397709 100644 --- a/src/locker/plugin/clock.hpp +++ b/src/locker/plugin/clock.hpp @@ -7,15 +7,16 @@ #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" -class WayfireLockerClockPlugin: public WayfireLockerPlugin{ - public: +class WayfireLockerClockPlugin : public WayfireLockerPlugin +{ + public: WayfireLockerClockPlugin(); void add_output(int id, Gtk::Grid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; - WfOption enable{"locker/clock_enable"}; + WfOption enable{"locker/clock_enable"}; WfOption format{"locker/clock_format"}; sigc::connection timeout; @@ -23,7 +24,7 @@ class WayfireLockerClockPlugin: public WayfireLockerPlugin{ void update_time(); std::unordered_map> labels; - std::string label_contents=""; + std::string label_contents = ""; }; -#endif \ No newline at end of file +#endif diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 5c134e2a..2eb04585 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -12,11 +12,11 @@ #include "fingerprint.hpp" -WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : +WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : dbus_name_id(Gio::DBus::own_name(Gio::DBus::BusType::SYSTEM, "net.reactivated.Fprint", - sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))) - {} + sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))) +{} WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() { @@ -26,124 +26,129 @@ WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() } } -void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr & connection, const Glib::ustring & name) +void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr & connection, + const Glib::ustring & name) { /* Bail here if config has this disabled */ if (!enable) { return; } + Gio::DBus::Proxy::create(connection, "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager", "net.reactivated.Fprint.Manager", - [this, connection] (const Glib::RefPtr & result) { - auto manager_proxy = Gio::DBus::Proxy::create_finish(result); - auto variant = manager_proxy->call_sync("GetDefaultDevice"); - Glib::Variant item_path; - variant.get_child(item_path,0); - Gio::DBus::Proxy::create(connection, - "net.reactivated.Fprint", - item_path.get(), - "net.reactivated.Fprint.Device", - sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_device_acquired) - ); - - } - ); + [this, connection] (const Glib::RefPtr & result) + { + auto manager_proxy = Gio::DBus::Proxy::create_finish(result); + auto variant = manager_proxy->call_sync("GetDefaultDevice"); + Glib::Variant item_path; + variant.get_child(item_path, 0); + Gio::DBus::Proxy::create(connection, + "net.reactivated.Fprint", + item_path.get(), + "net.reactivated.Fprint.Device", + sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_device_acquired)); + }); } void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr & result) { - device_proxy = Gio::DBus::Proxy::create_finish(result); - char* username = getlogin(); + device_proxy = Gio::DBus::Proxy::create_finish(result); + char *username = getlogin(); update_labels("Listing fingers..."); - auto reply = device_proxy->call_sync("ListEnrolledFingers", nullptr, Glib::Variant>::create(username)); - if(reply.get_n_children()>0) + auto reply = device_proxy->call_sync("ListEnrolledFingers", nullptr, + Glib::Variant>::create(username)); + if (reply.get_n_children() > 0) { // User has at least one fingerprint on file! update_labels("Fingerprint Ready"); update_image("fingerprint"); - } else { + } else + { // Zero fingers for this user. update_labels("No fingerprints enrolled"); update_image("nofingerprint"); } + Glib::Variant finger; reply.get_child(finger, 0); update_labels("Claiming device..."); device_proxy->signal_signal().connect([this] (const Glib::ustring & sender_name, - const Glib::ustring & signal_name, - const Glib::VariantContainerBase & params){ + const Glib::ustring & signal_name, + const Glib::VariantContainerBase & params) + { if (signal_name == "VerifyStatus") { Glib::Variant mesg; Glib::Variant done; - params.get_child(mesg,0); + params.get_child(mesg, 0); params.get_child(done, 1); update_labels(mesg.get()); - if(mesg.get() == "verify-match") + if (mesg.get() == "verify-match") { WayfireLockerApp::get().unlock(); } - if(mesg.get() == "verify-no-match") + + if (mesg.get() == "verify-no-match") { /* Reschedule fingerprint scan */ Glib::signal_timeout().connect_seconds( - [this](){ + [this] () + { this->start_fingerprint_scanning(); return G_SOURCE_REMOVE; }, 5); update_image("nofingerprint"); update_labels("Invalid fingerprint"); } - if(done.get()){ - is_scanning=false; + + if (done.get()) + { + is_scanning = false; device_proxy->call_sync("VerifyStop"); } } - },false); + }, false); device_proxy->call_sync("Claim", nullptr, Glib::Variant>::create({username})); finger_name = finger.get(); /* Start fingerprint reader 5 seconds after start - This fixes an issue where the fingerprint reader - is a button which locks the screen */ + * This fixes an issue where the fingerprint reader + * is a button which locks the screen */ Glib::signal_timeout().connect_seconds( - [this](){ - this->start_fingerprint_scanning(); - return G_SOURCE_REMOVE; - }, 5); + [this] () + { + this->start_fingerprint_scanning(); + return G_SOURCE_REMOVE; + }, 5); } void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() { - if(device_proxy && !is_scanning) + if (device_proxy && !is_scanning) { update_labels("Use fingerprint to unlock"); - is_scanning=true; + is_scanning = true; device_proxy->call_sync("VerifyStart", nullptr, - Glib::Variant>::create({finger_name}) - ); + Glib::Variant>::create({finger_name})); } else { update_labels("Unable to start fingerprint scan"); } } - - -void WayfireLockerFingerprintPlugin::init() +void WayfireLockerFingerprintPlugin::init() { WfOption enabled{"locker/fingerprint_enable"}; - enable=enabled; + enable = enabled; - // If no device : set enable = false + // If no device : set enable = false } - -void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid* grid) +void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid *grid) { labels.emplace(id, std::shared_ptr(new Gtk::Label())); images.emplace(id, std::shared_ptr(new Gtk::Image())); @@ -157,7 +162,7 @@ void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid* grid) image->add_css_class("fingerprint-icon"); label->add_css_class("fingerprint-text"); - Gtk::Box* box = get_plugin_position(WfOption{"locker/fingerprint_position"}, grid); + Gtk::Box *box = get_plugin_position(WfOption{"locker/fingerprint_position"}, grid); box->append(*image); box->append(*label); @@ -176,18 +181,20 @@ bool WayfireLockerFingerprintPlugin::should_enable() void WayfireLockerFingerprintPlugin::update_image(std::string image) { - for (auto& it: images) + for (auto& it : images) { it.second->set_from_icon_name(image); } + icon_contents = image; } void WayfireLockerFingerprintPlugin::update_labels(std::string text) { - for (auto& it: labels) + for (auto& it : labels) { it.second->set_label(text); } + label_contents = text; -} \ No newline at end of file +} diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 47b59ffd..d0cd81d6 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -10,8 +10,9 @@ #include "giomm/dbusproxy.h" #include "glibmm/refptr.h" -class WayfireLockerFingerprintPlugin: public WayfireLockerPlugin{ - public: +class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin +{ + public: guint dbus_name_id; Glib::RefPtr device_proxy; @@ -32,9 +33,9 @@ class WayfireLockerFingerprintPlugin: public WayfireLockerPlugin{ std::unordered_map> labels; std::unordered_map> images; - std::string icon_contents=""; - std::string label_contents=""; - std::string finger_name=""; + std::string icon_contents = ""; + std::string label_contents = ""; + std::string finger_name = ""; }; -#endif \ No newline at end of file +#endif diff --git a/src/locker/plugin/instant.cpp b/src/locker/plugin/instant.cpp index 563660ec..e395896e 100644 --- a/src/locker/plugin/instant.cpp +++ b/src/locker/plugin/instant.cpp @@ -6,7 +6,7 @@ bool WayfireLockerInstantPlugin::should_enable() { - return (bool) enable; + return (bool)enable; } void WayfireLockerInstantPlugin::add_output(int id, Gtk::Grid *grid) @@ -16,10 +16,11 @@ void WayfireLockerInstantPlugin::add_output(int id, Gtk::Grid *grid) button->set_label("Press to unlock"); button->add_css_class("instant-unlock"); - Gtk::Box* box = get_plugin_position(WfOption{"locker/instant_unlock_position"}, grid); + Gtk::Box *box = get_plugin_position(WfOption{"locker/instant_unlock_position"}, grid); box->append(*button); - button->signal_clicked().connect([](){ + button->signal_clicked().connect([] () + { WayfireLockerApp::get().unlock(); }, false); } @@ -30,6 +31,4 @@ void WayfireLockerInstantPlugin::remove_output(int id) } void WayfireLockerInstantPlugin::init() -{ - -} \ No newline at end of file +{} diff --git a/src/locker/plugin/instant.hpp b/src/locker/plugin/instant.hpp index 9b071a91..ce5c5b6d 100644 --- a/src/locker/plugin/instant.hpp +++ b/src/locker/plugin/instant.hpp @@ -6,18 +6,19 @@ #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" -class WayfireLockerInstantPlugin: public WayfireLockerPlugin{ - public: - WayfireLockerInstantPlugin(){}; +class WayfireLockerInstantPlugin : public WayfireLockerPlugin +{ + public: + WayfireLockerInstantPlugin() + {} void add_output(int id, Gtk::Grid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; - WfOption enable{"locker/instant_unlock_enable"}; + WfOption enable{"locker/instant_unlock_enable"}; std::unordered_map> buttons; - }; -#endif \ No newline at end of file +#endif diff --git a/src/locker/plugin/password.cpp b/src/locker/plugin/password.cpp index 1d73ab4e..a5fb3dfd 100644 --- a/src/locker/plugin/password.cpp +++ b/src/locker/plugin/password.cpp @@ -14,20 +14,22 @@ bool WayfireLockerPasswordPlugin::should_enable() { - return (bool) enable; + return (bool)enable; } -void WayfireLockerPasswordPlugin::update_labels(std::string text){ +void WayfireLockerPasswordPlugin::update_labels(std::string text) +{ for (auto& it : labels) { it.second->set_label(text); } + label_contents = text; } void WayfireLockerPasswordPlugin::blank_passwords() { - for (auto& it : entries) + for (auto& it : entries) { it.second->set_text(""); } @@ -45,103 +47,110 @@ void WayfireLockerPasswordPlugin::add_output(int id, Gtk::Grid *grid) label->set_label(label_contents); entry->set_visibility(false); /* Set entry callback for return */ - entry->signal_activate().connect([this, entry](){ - auto password = entry->get_text(); - if(password.length() > 0 ) - { - submit_user_password(password); - } - },true); + entry->signal_activate().connect([this, entry] () + { + auto password = entry->get_text(); + if (password.length() > 0) + { + submit_user_password(password); + } + }, true); /* Add to window */ - Gtk::Box* box = get_plugin_position(WfOption{"locker/password_position"}, grid); + Gtk::Box *box = get_plugin_position(WfOption{"locker/password_position"}, grid); box->append(*entry); box->append(*label); } void WayfireLockerPasswordPlugin::remove_output(int id) { - labels.erase(id); - entries.erase(id); + labels.erase(id); + entries.erase(id); } WayfireLockerPasswordPlugin::WayfireLockerPasswordPlugin() -{ -} +{} /* PAM password C code... */ -int pam_conversation(int num_mesg, const struct pam_message **mesg, struct pam_response **resp, void *appdata_ptr) +int pam_conversation(int num_mesg, const struct pam_message **mesg, struct pam_response **resp, + void *appdata_ptr) { - std::cout << "PAM convo step ... " << std::endl; - - WayfireLockerPasswordPlugin* pass_plugin = (WayfireLockerPasswordPlugin*)appdata_ptr; - *resp = (struct pam_response*) calloc(num_mesg, sizeof(struct pam_response)); - if(*resp == NULL) - { - std::cerr << "PAM reply allocation failed" <msg << std::endl; - resp[count]->resp_retcode = 0; - /* Echo OFF prompt should be user password. */ - if (mesg[count]->msg_style == PAM_PROMPT_ECHO_OFF) + std::cout << "PAM convo step ... " << std::endl; + + WayfireLockerPasswordPlugin *pass_plugin = (WayfireLockerPasswordPlugin*)appdata_ptr; + *resp = (struct pam_response*)calloc(num_mesg, sizeof(struct pam_response)); + if (*resp == NULL) { - resp[count]->resp = strdup(pass_plugin->submitted_password.c_str()); + std::cerr << "PAM reply allocation failed" << std::endl; + return PAM_ABORT; + } - } else if (mesg[count]->msg_style == PAM_ERROR_MSG) { - pass_plugin->update_labels(mesg[count]->msg); - } else if (mesg[count]->msg_style == PAM_TEXT_INFO) { - pass_plugin->update_labels(mesg[count]->msg); + for (int count = 0; count < num_mesg; count++) + { + std::cout << "PAM msg : " << mesg[count]->msg << std::endl; + resp[count]->resp_retcode = 0; + /* Echo OFF prompt should be user password. */ + if (mesg[count]->msg_style == PAM_PROMPT_ECHO_OFF) + { + resp[count]->resp = strdup(pass_plugin->submitted_password.c_str()); + } else if (mesg[count]->msg_style == PAM_ERROR_MSG) + { + pass_plugin->update_labels(mesg[count]->msg); + } else if (mesg[count]->msg_style == PAM_TEXT_INFO) + { + pass_plugin->update_labels(mesg[count]->msg); + } } - } - return PAM_SUCCESS; + + return PAM_SUCCESS; } void WayfireLockerPasswordPlugin::submit_user_password(std::string password) { - submitted_password = password; - blank_passwords(); - std::cout << "Unlocking ... " << std::endl; - /* Get username*/ - char* username = getlogin(); - /* Init PAM conversation */ - const struct pam_conv local_conversation = { pam_conversation, this}; - pam_handle_t *local_auth_handle = NULL; // this gets set by pam_start - int retval; - /* Start the password-based conversation */ - std::cout << "PAM start ... " << std::endl; - retval = pam_start("wf-locker-password", username, &local_conversation, &local_auth_handle); - if (retval != PAM_SUCCESS) - { - /* We don't expect to be here. No graceful way out of this. */ - std::cout << "PAM start returned " << retval << std::endl; - update_labels("pam_start failure"); - exit(retval); - } - std::cout << "PAM auth ... " << std::endl; - /* Request authenticate */ - retval = pam_authenticate(local_auth_handle, 0); - bool unlock = false; - if (retval != PAM_SUCCESS) - { - if (retval == PAM_AUTH_ERR) + submitted_password = password; + blank_passwords(); + std::cout << "Unlocking ... " << std::endl; + /* Get username*/ + char *username = getlogin(); + /* Init PAM conversation */ + const struct pam_conv local_conversation = { + pam_conversation, this + }; + pam_handle_t *local_auth_handle = NULL; // this gets set by pam_start + int retval; + /* Start the password-based conversation */ + std::cout << "PAM start ... " << std::endl; + retval = pam_start("wf-locker-password", username, &local_conversation, &local_auth_handle); + if (retval != PAM_SUCCESS) { - std::cout << "Authentication failure." << std::endl; - update_labels("Authentication failure."); + /* We don't expect to be here. No graceful way out of this. */ + std::cout << "PAM start returned " << retval << std::endl; + update_labels("pam_start failure"); + exit(retval); + } + + std::cout << "PAM auth ... " << std::endl; + /* Request authenticate */ + retval = pam_authenticate(local_auth_handle, 0); + bool unlock = false; + if (retval != PAM_SUCCESS) + { + if (retval == PAM_AUTH_ERR) + { + std::cout << "Authentication failure." << std::endl; + update_labels("Authentication failure."); + } + } else + { + std::cout << "Authenticate success." << std::endl; + unlock = true; + } + + retval = pam_end(local_auth_handle, retval); + if (unlock) + { + WayfireLockerApp::get().unlock(); } - } else { - std::cout << "Authenticate success." << std::endl; - unlock = true; - } - retval = pam_end(local_auth_handle, retval); - if (unlock) - { - WayfireLockerApp::get().unlock(); - } } void WayfireLockerPasswordPlugin::init() -{ - -} \ No newline at end of file +{} diff --git a/src/locker/plugin/password.hpp b/src/locker/plugin/password.hpp index 77b7f016..88e5f4bb 100644 --- a/src/locker/plugin/password.hpp +++ b/src/locker/plugin/password.hpp @@ -7,10 +7,12 @@ #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" -int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); +int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, + void *appdata_ptr); -class WayfireLockerPasswordPlugin: public WayfireLockerPlugin{ - public: +class WayfireLockerPasswordPlugin : public WayfireLockerPlugin +{ + public: WayfireLockerPasswordPlugin(); void add_output(int id, Gtk::Grid *grid) override; void remove_output(int id) override; @@ -26,8 +28,8 @@ class WayfireLockerPasswordPlugin: public WayfireLockerPlugin{ std::unordered_map> labels; std::unordered_map> entries; - std::string label_contents=""; + std::string label_contents = ""; std::string submitted_password = ""; }; -#endif \ No newline at end of file +#endif diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index 2a21403f..983a2755 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -16,29 +16,30 @@ /* - To set the PIN Hash required to enable this plugin, try running - `echo -n "1234" | sha512sum | head -c 128 > ~/.config/wf-locker.hash` - - Replace the numbers inside the echo quote. There must be one or more digits, - and any non-digit will render it impossible to unlock. + * To set the PIN Hash required to enable this plugin, try running + * `echo -n "1234" | sha512sum | head -c 128 > ~/.config/wf-locker.hash` + * + * Replace the numbers inside the echo quote. There must be one or more digits, + * and any non-digit will render it impossible to unlock. */ PinPad::PinPad() { - for (int count = 0; count < 10; count ++) + for (int count = 0; count < 10; count++) { std::string number = std::to_string(count); numbers[count].add_css_class("pinpad-number"); numbers[count].add_css_class("pinpad-button"); numbers[count].set_label(number); numbers[count].signal_clicked().connect( - [number] () { - auto plugin = WayfireLockerApp::get().get_plugin("pin"); - auto plugin_cast = std::dynamic_pointer_cast(plugin); - plugin_cast->add_digit(number); - } - ); + [number] () + { + auto plugin = WayfireLockerApp::get().get_plugin("pin"); + auto plugin_cast = std::dynamic_pointer_cast(plugin); + plugin_cast->add_digit(number); + }); } + bsub.set_label("✔️"); bcan.set_label("❌"); bsub.add_css_class("pinpad-submit"); @@ -46,40 +47,39 @@ PinPad::PinPad() bcan.add_css_class("pinpad-cancel"); bcan.add_css_class("pinpad-button"); bcan.signal_clicked().connect( - []() { - auto plugin = WayfireLockerApp::get().get_plugin("pin"); - auto plugin_cast = std::dynamic_pointer_cast(plugin); - plugin_cast->reset_pin(); - } - ); + [] () + { + auto plugin = WayfireLockerApp::get().get_plugin("pin"); + auto plugin_cast = std::dynamic_pointer_cast(plugin); + plugin_cast->reset_pin(); + }); bsub.signal_clicked().connect( - [] () { - auto plugin = WayfireLockerApp::get().get_plugin("pin"); - auto plugin_cast = std::dynamic_pointer_cast(plugin); - plugin_cast->submit_pin(); - } - ); + [] () + { + auto plugin = WayfireLockerApp::get().get_plugin("pin"); + auto plugin_cast = std::dynamic_pointer_cast(plugin); + plugin_cast->submit_pin(); + }); label.add_css_class("pinpad-current"); } PinPad::~PinPad() -{ -} +{} void PinPad::init() { attach(label, 0, 0, 3); - attach(numbers[1],0,1); - attach(numbers[2], 1,1); + attach(numbers[1], 0, 1); + attach(numbers[2], 1, 1); attach(numbers[3], 2, 1); - attach(numbers[4],0,2); - attach(numbers[5], 1,2); + attach(numbers[4], 0, 2); + attach(numbers[5], 1, 2); attach(numbers[6], 2, 2); - attach(numbers[7],0,3); - attach(numbers[8], 1,3); + attach(numbers[7], 0, 3); + attach(numbers[8], 1, 3); attach(numbers[9], 2, 3); attach(bsub, 2, 4); - attach(numbers[0],1, 4); + attach(numbers[0], 1, 4); attach(bcan, 0, 4); set_vexpand(true); set_column_homogeneous(true); @@ -90,16 +90,16 @@ WayfireLockerPinPlugin::WayfireLockerPinPlugin() { WfOption enabled{"locker/pin_enable"}; enable = enabled; - if(!enable) + if (!enable) { return; } - + /* TODO ... */ - //if (cmdline_config.has_value()) - //{ - // return cmdline_config.value(); - //} + // if (cmdline_config.has_value()) + // { + // return cmdline_config.value(); + // } std::string config_dir; char *config_home = getenv("XDG_CONFIG_HOME"); @@ -112,29 +112,33 @@ WayfireLockerPinPlugin::WayfireLockerPinPlugin() } std::ifstream f(config_dir + "/wf-locker.hash"); - if(!f.is_open()){ + if (!f.is_open()) + { std::cerr << "No PIN hash set" << std::endl; enable = false; return; } std::string s; - if(!getline(f,s)){ + if (!getline(f, s)) + { std::cerr << "No PIN hash set" << std::endl; enable = false; return; } - if(s.length() != 128){ + + if (s.length() != 128) + { std::cerr << "Invalid PIN hash" << std::endl; - enable= false; + enable = false; return; } + pinhash = s; } void WayfireLockerPinPlugin::init() -{ -} +{} bool WayfireLockerPinPlugin::should_enable() { @@ -147,7 +151,7 @@ void WayfireLockerPinPlugin::add_output(int id, Gtk::Grid *grid) auto pinpad = pinpads[id]; pinpad->add_css_class("pinpad"); pinpad->init(); - Gtk::Box* box = get_plugin_position(WfOption{"locker/pin_position"}, grid); + Gtk::Box *box = get_plugin_position(WfOption{"locker/pin_position"}, grid); box->append(*pinpad); update_labels(); /* Update all to set this one? maybe overkill */ } @@ -172,7 +176,7 @@ void WayfireLockerPinPlugin::reset_pin() void WayfireLockerPinPlugin::update_labels() { std::string asterisks(pin.length(), '*'); - for(auto& it: pinpads) + for (auto& it : pinpads) { it.second->label.set_label(asterisks); } @@ -185,6 +189,7 @@ void WayfireLockerPinPlugin::submit_pin() { WayfireLockerApp::get().unlock(); } + pin = ""; update_labels(); } @@ -198,11 +203,13 @@ std::string WayfireLockerPinPlugin::sha512(const std::string input) EVP_DigestUpdate(mdctx, input.c_str(), input.size()); EVP_DigestFinal(mdctx, hash, &hash_length); EVP_MD_CTX_free(mdctx); - + std::stringstream ss; - for(int i = 0; i < SHA512_DIGEST_LENGTH; i++){ - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast( hash[i] ); + for (int i = 0; i < SHA512_DIGEST_LENGTH; i++) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(hash[i]); } + return ss.str(); -} \ No newline at end of file +} diff --git a/src/locker/plugin/pin.hpp b/src/locker/plugin/pin.hpp index bfa2c018..1df67041 100644 --- a/src/locker/plugin/pin.hpp +++ b/src/locker/plugin/pin.hpp @@ -11,8 +11,9 @@ /* Rather than keep an unordered list for each widget, put them together */ class WayfireLockerPinPlugin; -class PinPad : public Gtk::Grid{ - public: +class PinPad : public Gtk::Grid +{ + public: PinPad(); ~PinPad(); Gtk::Button bsub, bcan; @@ -20,11 +21,11 @@ class PinPad : public Gtk::Grid{ void init(); void check(); Gtk::Button numbers[10]; - }; -class WayfireLockerPinPlugin: public WayfireLockerPlugin{ - public: +class WayfireLockerPinPlugin : public WayfireLockerPlugin +{ + public: WayfireLockerPinPlugin(); void add_output(int id, Gtk::Grid *grid) override; void remove_output(int id) override; @@ -37,12 +38,12 @@ class WayfireLockerPinPlugin: public WayfireLockerPlugin{ void add_digit(std::string digit); std::string sha512(const std::string input); - bool enable= false; + bool enable = false; std::unordered_map> pinpads; - std::string pin=""; - std::string pinhash="nope"; + std::string pin = ""; + std::string pinhash = "nope"; }; -#endif \ No newline at end of file +#endif From 2593db011e67b35daff09c6e31b32b618ee63e0a Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 18:12:41 +0000 Subject: [PATCH 06/35] - include locker.xml in install --- metadata/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/metadata/meson.build b/metadata/meson.build index eb98e8c2..18c0b544 100644 --- a/metadata/meson.build +++ b/metadata/meson.build @@ -7,3 +7,4 @@ configure_file(input: 'background.xml.in', output: 'background.xml', install_data('dock.xml', install_dir: metadata_dir) install_data('panel.xml', install_dir: metadata_dir) +install_data('locker.xml', install_dir: metadata_dir) From 65064c36fe344b8b81d033c05afe6ce4868c9475 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 18:14:32 +0000 Subject: [PATCH 07/35] - more uncrust --- src/util/wf-shell-app.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/util/wf-shell-app.cpp b/src/util/wf-shell-app.cpp index 31c7c927..7883ecbe 100644 --- a/src/util/wf-shell-app.cpp +++ b/src/util/wf-shell-app.cpp @@ -224,7 +224,6 @@ void WayfireShellApp::on_activate() if (!alternative_monitors) { - // Hook up monitor tracking auto display = Gdk::Display::get_default(); auto monitors = display->get_monitors(); From 71307fadfab2835db6d38163a9aabd3ff8707f53 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 18:53:55 +0000 Subject: [PATCH 08/35] - It should exit if not supported --- src/locker/locker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 7b51ce96..23580632 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -176,6 +176,7 @@ int main(int argc, char **argv) if (!gtk_session_lock_is_supported()) { std::cerr << "This session does not support locking" << std::endl; + exit(0); } WayfireLockerApp::create(argc, argv); From d754ad286aca90a312c4db0a47154fd1835d30fb Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 19:37:32 +0000 Subject: [PATCH 09/35] - hopefully more graceful fail of fprintd --- src/locker/plugin/fingerprint.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 2eb04585..aa431b40 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "../../util/wf-option-wrap.hpp" #include "glib.h" #include "locker.hpp" @@ -42,9 +43,14 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr & result) { auto manager_proxy = Gio::DBus::Proxy::create_finish(result); - auto variant = manager_proxy->call_sync("GetDefaultDevice"); + auto variant = manager_proxy->call_sync("GetDevices"); + if(variant.get_n_children()==0){ + update_labels("No Fingerprint device found"); + return; + } + auto default_device = manager_proxy->call_sync("GetDefaultDevice"); Glib::Variant item_path; - variant.get_child(item_path, 0); + default_device.get_child(item_path, 0); Gio::DBus::Proxy::create(connection, "net.reactivated.Fprint", item_path.get(), From 36d876d1ad2ad45705a185b53732c30114e55583 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 19:38:19 +0000 Subject: [PATCH 10/35] - even more graceful? --- src/locker/plugin/fingerprint.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index aa431b40..f1652d27 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -46,6 +46,7 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtrcall_sync("GetDevices"); if(variant.get_n_children()==0){ update_labels("No Fingerprint device found"); + enable = false; return; } auto default_device = manager_proxy->call_sync("GetDefaultDevice"); From 004310d793315850ad9ac44921c5adf8f2fb2a2f Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 19:58:09 +0000 Subject: [PATCH 11/35] - maybe --- src/locker/plugin/fingerprint.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index f1652d27..310c642b 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -44,7 +44,10 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtrcall_sync("GetDevices"); - if(variant.get_n_children()==0){ + /* Decant the array from the tuple, count devices */ + Glib::Variant> array; + variant.get_child(array, 0); + if(array.get_n_children()==0){ update_labels("No Fingerprint device found"); enable = false; return; From 48465971d7ad759a1a2f1fe5579ddc67e84a6480 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 20:00:21 +0000 Subject: [PATCH 12/35] - allow disable internally --- src/locker/plugin/fingerprint.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 310c642b..e5cc2ffd 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -17,7 +17,10 @@ WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : dbus_name_id(Gio::DBus::own_name(Gio::DBus::BusType::SYSTEM, "net.reactivated.Fprint", sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))) -{} +{ + WfOption enabled{"locker/fingerprint_enable"}; + enable = enabled; +} WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() { @@ -152,7 +155,6 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() void WayfireLockerFingerprintPlugin::init() { - WfOption enabled{"locker/fingerprint_enable"}; enable = enabled; // If no device : set enable = false From 1fc725ab4700ebc1f6358c0c82a546d21cf6a477 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 20:01:19 +0000 Subject: [PATCH 13/35] - fix fingerprint again --- src/locker/plugin/fingerprint.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index e5cc2ffd..200531d8 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -155,9 +155,6 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() void WayfireLockerFingerprintPlugin::init() { - enable = enabled; - - // If no device : set enable = false } void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid *grid) From 33d7349734c281bf5cf970b15fc6e2d0560e309f Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 20:17:21 +0000 Subject: [PATCH 14/35] - more guardrails --- src/locker/plugin/fingerprint.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 200531d8..ad42b099 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -16,10 +16,9 @@ WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : dbus_name_id(Gio::DBus::own_name(Gio::DBus::BusType::SYSTEM, "net.reactivated.Fprint", - sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))) + sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))), + enable(WfOption {"locker/fingerprint_enable"}) { - WfOption enabled{"locker/fingerprint_enable"}; - enable = enabled; } WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() @@ -51,7 +50,7 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr> array; variant.get_child(array, 0); if(array.get_n_children()==0){ - update_labels("No Fingerprint device found"); + update_labels("No Fingerprint device found : removing"); enable = false; return; } @@ -73,7 +72,10 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_sync("ListEnrolledFingers", nullptr, Glib::Variant>::create(username)); - if (reply.get_n_children() > 0) + Glib::Variant> array; + reply.get_child(array, 0); + + if (array.get_n_children() > 0) { // User has at least one fingerprint on file! update_labels("Fingerprint Ready"); @@ -83,11 +85,13 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr finger; reply.get_child(finger, 0); - update_labels("Claiming device..."); + update_labels("Finger print device found"); device_proxy->signal_signal().connect([this] (const Glib::ustring & sender_name, const Glib::ustring & signal_name, const Glib::VariantContainerBase & params) @@ -140,9 +144,13 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_sync("VerifyStart", nullptr, From 3a055917603dc21630679ff24b60acfc7baebb29 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 20:30:32 +0000 Subject: [PATCH 15/35] - hide fprintd plugin on simple failures --- src/locker/plugin/fingerprint.cpp | 43 ++++++++++++++++++++++++++++--- src/locker/plugin/fingerprint.hpp | 3 +++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index ad42b099..95ad9a4f 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -49,9 +49,10 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr> array; variant.get_child(array, 0); - if(array.get_n_children()==0){ - update_labels("No Fingerprint device found : removing"); + if(array.get_n_children()==0) + { enable = false; + hide(); return; } auto default_device = manager_proxy->call_sync("GetDefaultDevice"); @@ -78,11 +79,13 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr 0) { // User has at least one fingerprint on file! + show(); update_labels("Fingerprint Ready"); update_image("fingerprint"); } else { // Zero fingers for this user. + show(); update_labels("No fingerprints enrolled"); update_image("nofingerprint"); // Don't hide entirely, allow the user to see this specific fail @@ -117,6 +120,7 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrstart_fingerprint_scanning(); return G_SOURCE_REMOVE; }, 5); + show(); update_image("nofingerprint"); update_labels("Invalid fingerprint"); } @@ -150,7 +154,8 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() } if (device_proxy && !is_scanning) { - update_labels("Press to unlock : '"+finger_name+"'"); + show(); + update_labels("Use fingerprint to unlock"); is_scanning = true; device_proxy->call_sync("VerifyStart", nullptr, @@ -173,6 +178,12 @@ void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid *grid) auto image = images[id]; auto label = labels[id]; + if(!show_state) + { + image->hide(); + label->hide(); + } + image->set_from_icon_name("fingerprint"); label->set_label("No Fingerprint device found"); @@ -215,3 +226,29 @@ void WayfireLockerFingerprintPlugin::update_labels(std::string text) label_contents = text; } + + +void WayfireLockerFingerprintPlugin::hide() +{ + show_state = false; + for (auto& it : labels) + { + it.second->hide(); + } + for (auto& it : images) + { + it.second->hide(); + } +} +void WayfireLockerFingerprintPlugin::show() +{ + show_state = true; + for (auto& it : labels) + { + it.second->show(); + } + for (auto& it : images) + { + it.second->show(); + } +} \ No newline at end of file diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index d0cd81d6..4d311031 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -25,9 +25,12 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin void remove_output(int id) override; bool should_enable() override; void init() override; + void hide(); + void show(); bool enable; bool is_scanning; + bool show_state=false; void update_labels(std::string text); void update_image(std::string image); From 0a89625758b1d19881673b4f00b5cdc0d9174fe0 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 20:37:08 +0000 Subject: [PATCH 16/35] - hide battery in unknown state --- src/locker/plugin/battery.cpp | 47 +++++++++++++++++++++++++++++++++++ src/locker/plugin/battery.hpp | 3 +++ 2 files changed, 50 insertions(+) diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index 7cf9972a..6fc687c1 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -102,6 +102,13 @@ void WayfireLockerBatteryPlugin::add_output(int id, Gtk::Grid *grid) auto subtext = subtexts[id]; auto image = images[id]; + if(!show_state) + { + label->hide(); + subtext->hide(); + image->hide(); + } + label->add_css_class("battery-percent"); subtext->add_css_class("battery-description"); image->add_css_class("battery-image"); @@ -232,7 +239,47 @@ void WayfireLockerBatteryPlugin::update_details() description += ", " + uint_to_time(time_to_empty.get()) + " remaining"; } + if(state == 0) /* Unknown */ + { + hide(); + return; + } + show(); update_descriptions(get_device_type_description(type.get()) + description); update_percentages(percentage_string); update_images(); } + + +void WayfireLockerBatteryPlugin::hide() +{ + show_state = false; + for (auto& it : labels) + { + it.second->hide(); + } + for (auto& it : images) + { + it.second->hide(); + } + for (auto &it : subtexts) + { + it.second->hide(); + } +} +void WayfireLockerBatteryPlugin::show() +{ + show_state = true; + for (auto& it : labels) + { + it.second->show(); + } + for (auto& it : images) + { + it.second->show(); + } + for (auto& it : subtexts) + { + it.second->show(); + } +} \ No newline at end of file diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index d7598805..7166db0a 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -43,6 +43,9 @@ class WayfireLockerBatteryPlugin : public WayfireLockerPlugin void remove_output(int id) override; bool should_enable() override; void init() override; + void hide(); + void show(); + bool show_state=true; WfOption battery_position{"locker/battery_position"}; WfOption enable{"locker/battery_enable"}; From f6cd3c8bb3970af0d5709b9f9a48ce9fb2553e32 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 20:43:55 +0000 Subject: [PATCH 17/35] - uncrustify --- src/locker/plugin/battery.cpp | 15 ++++++++++----- src/locker/plugin/battery.hpp | 2 +- src/locker/plugin/fingerprint.cpp | 22 ++++++++++++---------- src/locker/plugin/fingerprint.hpp | 2 +- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index 6fc687c1..9a8c88f2 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -102,7 +102,7 @@ void WayfireLockerBatteryPlugin::add_output(int id, Gtk::Grid *grid) auto subtext = subtexts[id]; auto image = images[id]; - if(!show_state) + if (!show_state) { label->hide(); subtext->hide(); @@ -239,18 +239,18 @@ void WayfireLockerBatteryPlugin::update_details() description += ", " + uint_to_time(time_to_empty.get()) + " remaining"; } - if(state == 0) /* Unknown */ + if (state == 0) /* Unknown */ { hide(); return; } + show(); update_descriptions(get_device_type_description(type.get()) + description); update_percentages(percentage_string); update_images(); } - void WayfireLockerBatteryPlugin::hide() { show_state = false; @@ -258,15 +258,18 @@ void WayfireLockerBatteryPlugin::hide() { it.second->hide(); } + for (auto& it : images) { it.second->hide(); } - for (auto &it : subtexts) + + for (auto & it : subtexts) { it.second->hide(); } } + void WayfireLockerBatteryPlugin::show() { show_state = true; @@ -274,12 +277,14 @@ void WayfireLockerBatteryPlugin::show() { it.second->show(); } + for (auto& it : images) { it.second->show(); } + for (auto& it : subtexts) { it.second->show(); } -} \ No newline at end of file +} diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index 7166db0a..641539ad 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -45,7 +45,7 @@ class WayfireLockerBatteryPlugin : public WayfireLockerPlugin void init() override; void hide(); void show(); - bool show_state=true; + bool show_state = true; WfOption battery_position{"locker/battery_position"}; WfOption enable{"locker/battery_enable"}; diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 95ad9a4f..d1f89f70 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -17,9 +17,8 @@ WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : dbus_name_id(Gio::DBus::own_name(Gio::DBus::BusType::SYSTEM, "net.reactivated.Fprint", sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))), - enable(WfOption {"locker/fingerprint_enable"}) -{ -} + enable(WfOption{"locker/fingerprint_enable"}) +{} WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() { @@ -49,12 +48,13 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr> array; variant.get_child(array, 0); - if(array.get_n_children()==0) + if (array.get_n_children() == 0) { enable = false; hide(); return; } + auto default_device = manager_proxy->call_sync("GetDefaultDevice"); Glib::Variant item_path; default_device.get_child(item_path, 0); @@ -148,10 +148,11 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrhide(); label->hide(); @@ -227,7 +227,6 @@ void WayfireLockerFingerprintPlugin::update_labels(std::string text) label_contents = text; } - void WayfireLockerFingerprintPlugin::hide() { show_state = false; @@ -235,11 +234,13 @@ void WayfireLockerFingerprintPlugin::hide() { it.second->hide(); } + for (auto& it : images) { it.second->hide(); } } + void WayfireLockerFingerprintPlugin::show() { show_state = true; @@ -247,8 +248,9 @@ void WayfireLockerFingerprintPlugin::show() { it.second->show(); } + for (auto& it : images) { it.second->show(); } -} \ No newline at end of file +} diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 4d311031..22392bed 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -30,7 +30,7 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin bool enable; bool is_scanning; - bool show_state=false; + bool show_state = false; void update_labels(std::string text); void update_image(std::string image); From f425cc56bbe1497f106d1b0643edfa4db4572e64 Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 00:46:49 +0000 Subject: [PATCH 18/35] - Improved (?) dbus error catching - Delay and Retry claiming finger print reader on failure - Remove saving and using of name of fingerprint to request as we weren't using it anyway - Added volume mute & mic mute plugin --- metadata/locker.xml | 46 ++++++++ src/locker/locker.cpp | 2 + src/locker/meson.build | 9 +- src/locker/plugin/fingerprint.cpp | 68 ++++++++---- src/locker/plugin/fingerprint.hpp | 2 +- src/locker/plugin/volume.cpp | 177 ++++++++++++++++++++++++++++++ src/locker/plugin/volume.hpp | 42 +++++++ src/panel/widgets/volume.hpp | 1 + 8 files changed, 317 insertions(+), 30 deletions(-) create mode 100644 src/locker/plugin/volume.cpp create mode 100644 src/locker/plugin/volume.hpp diff --git a/metadata/locker.xml b/metadata/locker.xml index 740fc696..201dfb37 100644 --- a/metadata/locker.xml +++ b/metadata/locker.xml @@ -295,6 +295,52 @@ 96 16 + + + + + <_short>Instant Unlock diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 23580632..314d15d5 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -22,6 +22,7 @@ #include "plugin/password.hpp" #include "plugin/pin.hpp" #include "plugin/fingerprint.hpp" +#include "plugin/volume.hpp" #include "wf-shell-app.hpp" #include @@ -64,6 +65,7 @@ void WayfireLockerApp::on_activate() plugins.emplace("instant", (Plugin(new WayfireLockerInstantPlugin()))); plugins.emplace("pin", Plugin(new WayfireLockerPinPlugin())); plugins.emplace("fingerprint", Plugin(new WayfireLockerFingerprintPlugin())); + plugins.emplace("volume", Plugin(new WayfireLockerVolumePlugin())); for (auto& it : plugins) { diff --git a/src/locker/meson.build b/src/locker/meson.build index f74f474b..5af08aaa 100644 --- a/src/locker/meson.build +++ b/src/locker/meson.build @@ -19,11 +19,10 @@ deps = [ openssl ] -# We'll come back here with a 'mute mic' widget and a 'volume' widget -#if libpulse.found() -# widget_sources += 'widgets/volume.cpp' -# deps += [libpulse, libgvc] -#endif +if libpulse.found() + widget_sources += 'plugin/volume.cpp' + deps += [libpulse, libgvc] +endif executable( 'wf-locker', diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index d1f89f70..9da937e0 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -44,33 +44,31 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr & result) { auto manager_proxy = Gio::DBus::Proxy::create_finish(result); - auto variant = manager_proxy->call_sync("GetDevices"); - /* Decant the array from the tuple, count devices */ - Glib::Variant> array; - variant.get_child(array, 0); - if (array.get_n_children() == 0) + try + { + auto default_device = manager_proxy->call_sync("GetDefaultDevice"); + Glib::Variant item_path; + default_device.get_child(item_path, 0); + Gio::DBus::Proxy::create(connection, + "net.reactivated.Fprint", + item_path.get(), + "net.reactivated.Fprint.Device", + sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_device_acquired)); + } catch(Glib::Error e) /* TODO : Narrow down? */ { enable = false; hide(); return; } - - auto default_device = manager_proxy->call_sync("GetDefaultDevice"); - Glib::Variant item_path; - default_device.get_child(item_path, 0); - Gio::DBus::Proxy::create(connection, - "net.reactivated.Fprint", - item_path.get(), - "net.reactivated.Fprint.Device", - sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_device_acquired)); + }); } void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr & result) { device_proxy = Gio::DBus::Proxy::create_finish(result); - char *username = getlogin(); update_labels("Listing fingers..."); + char *username = getlogin(); auto reply = device_proxy->call_sync("ListEnrolledFingers", nullptr, Glib::Variant>::create(username)); Glib::Variant> array; @@ -95,6 +93,8 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr finger; reply.get_child(finger, 0); update_labels("Finger print device found"); + + /* Attach a listener now, useful when we start scanning */ device_proxy->signal_signal().connect([this] (const Glib::ustring & sender_name, const Glib::ustring & signal_name, const Glib::VariantContainerBase & params) @@ -132,18 +132,38 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_sync("Claim", nullptr, Glib::Variant>::create({username})); - finger_name = finger.get(); + claim_device(); +} + +void WayfireLockerFingerprintPlugin::claim_device() +{ + try + { + char *username = getlogin(); + device_proxy->call_sync("Claim", nullptr, Glib::Variant>::create({username})); + /* Start scanning in 5 seconds */ + Glib::signal_timeout().connect_seconds( + [this] () + { + this->start_fingerprint_scanning(); + return G_SOURCE_REMOVE; + }, 5); + }catch (Glib::Error e) /* TODO : Narrow down? */ + { + std::cout << "Fingerprint device already claimed, try in 5s"<claim_device(); + return G_SOURCE_REMOVE; + }, 5); + } /* Start fingerprint reader 5 seconds after start * This fixes an issue where the fingerprint reader * is a button which locks the screen */ - Glib::signal_timeout().connect_seconds( - [this] () - { - this->start_fingerprint_scanning(); - return G_SOURCE_REMOVE; - }, 5); + } void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() @@ -160,7 +180,7 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() is_scanning = true; device_proxy->call_sync("VerifyStart", nullptr, - Glib::Variant>::create({finger_name})); + Glib::Variant>::create({""})); } else { update_labels("Unable to start fingerprint scan"); diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 22392bed..817a7fd0 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -20,6 +20,7 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin ~WayfireLockerFingerprintPlugin(); void on_bus_acquired(const Glib::RefPtr & connection, const Glib::ustring & name); void on_device_acquired(const Glib::RefPtr & result); + void claim_device(); void start_fingerprint_scanning(); void add_output(int id, Gtk::Grid *grid) override; void remove_output(int id) override; @@ -38,7 +39,6 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin std::unordered_map> images; std::string icon_contents = ""; std::string label_contents = ""; - std::string finger_name = ""; }; #endif diff --git a/src/locker/plugin/volume.cpp b/src/locker/plugin/volume.cpp new file mode 100644 index 00000000..f59c8515 --- /dev/null +++ b/src/locker/plugin/volume.cpp @@ -0,0 +1,177 @@ +#include +#include +#include +#include "clock.hpp" + +#include "volume.hpp" + +static void default_sink_changed(GvcMixerControl *gvc_control, + guint id, gpointer user_data) +{ + WayfireLockerVolumePlugin *plugin = (WayfireLockerVolumePlugin*)user_data; + plugin->on_default_sink_changed(); +} + +static void default_source_changed(GvcMixerControl *gvc_control, + guint id, gpointer user_data) +{ + WayfireLockerVolumePlugin *plugin = (WayfireLockerVolumePlugin*)user_data; + plugin->on_default_source_changed(); +} + + +static void notify_sink_muted(GvcMixerControl *gvc_control, + guint id, gpointer user_data) +{ + WayfireLockerVolumePlugin *plugin = (WayfireLockerVolumePlugin*)user_data; + plugin->update_button_images(); +} + +static void notify_source_muted(GvcMixerControl *gvc_control, + guint id, gpointer user_data) +{ + WayfireLockerVolumePlugin *plugin = (WayfireLockerVolumePlugin*)user_data; + plugin->update_button_images(); +} + +void WayfireLockerVolumePlugin::update_button_images() +{ + + if (gvc_sink_stream) + { + for (auto& it : sink_buttons) + { + it.second->set_icon_name(gvc_mixer_stream_get_is_muted(gvc_sink_stream)?"audio-volume-muted-symbolic":"audio-volume-high-symbolic"); + } + } + if (gvc_source_stream) + { + for (auto& it : source_buttons) + { + it.second->set_icon_name(gvc_mixer_stream_get_is_muted(gvc_source_stream)?"microphone-sensitivity-muted-symbolic":"microphone-sensitivity-high-symbolic"); + } + } +} + +WayfireLockerVolumePlugin::WayfireLockerVolumePlugin() +{ + enable=WfOption{"locker/volume_enable"}; + /* Setup gvc control */ + gvc_control = gvc_mixer_control_new("Wayfire Volume Control"); + g_signal_connect(gvc_control, + "default-sink-changed", G_CALLBACK(default_sink_changed), this); + g_signal_connect(gvc_control, + "default-source-changed", G_CALLBACK(default_source_changed), this); + gvc_mixer_control_open(gvc_control); + +} + +bool WayfireLockerVolumePlugin::should_enable() +{ + return (bool)enable; +} + +void WayfireLockerVolumePlugin::add_output(int id, Gtk::Grid *grid) +{ + source_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); + sink_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); + auto source_button = source_buttons[id]; + auto sink_button = sink_buttons[id]; + + sink_button->add_css_class("volume-button"); + source_button->add_css_class("mic-button"); + + Gtk::Box *box = get_plugin_position(WfOption{"locker/volume_position"}, grid); + auto inner_box = Gtk::Box(); + inner_box.append(*source_button); + inner_box.append(*sink_button); + box->append(inner_box); + + sink_button->signal_clicked().connect( + [=] () { + if(!gvc_sink_stream) + { + return; + } + bool muted = gvc_mixer_stream_get_is_muted(gvc_sink_stream); + gvc_mixer_stream_change_is_muted(gvc_sink_stream, !muted); + gvc_mixer_stream_push_volume(gvc_sink_stream); + } + ); + source_button->signal_clicked().connect( + [=] () { + if(!gvc_source_stream) + { + return; + } + bool muted = gvc_mixer_stream_get_is_muted(gvc_source_stream); + gvc_mixer_stream_change_is_muted(gvc_source_stream, !muted); + gvc_mixer_stream_push_volume(gvc_source_stream); + } + ); + update_button_images(); +} + +void WayfireLockerVolumePlugin::remove_output(int id) +{ + source_buttons.erase(id); + sink_buttons.erase(id); +} + +void WayfireLockerVolumePlugin::init() +{ + +} + +void WayfireLockerVolumePlugin::disconnect_gvc_stream_sink_signals() +{ + + if (notify_sink_muted_signal) + { + g_signal_handler_disconnect(gvc_sink_stream, notify_sink_muted_signal); + } + + notify_sink_muted_signal = 0; +} +void WayfireLockerVolumePlugin::disconnect_gvc_stream_source_signals() +{ + + if (notify_source_muted_signal) + { + g_signal_handler_disconnect(gvc_source_stream, notify_source_muted_signal); + } + + notify_source_muted_signal = 0; +} + +void WayfireLockerVolumePlugin::on_default_sink_changed() +{ + gvc_sink_stream = gvc_mixer_control_get_default_sink(gvc_control); + if (!gvc_sink_stream) + { + printf("GVC: Failed to get default sink\n"); + return; + } + + /* Reconnect signals to new sink */ + disconnect_gvc_stream_sink_signals(); + notify_sink_muted_signal = g_signal_connect(gvc_sink_stream, "notify::is-muted", + G_CALLBACK(notify_sink_muted), this); + update_button_images(); +} + +void WayfireLockerVolumePlugin::on_default_source_changed() +{ + gvc_source_stream = gvc_mixer_control_get_default_source(gvc_control); + if (!gvc_source_stream) + { + printf("GVC: Failed to get default source\n"); + return; + } + + /* Reconnect signals to new source */ + disconnect_gvc_stream_source_signals(); + notify_source_muted_signal = g_signal_connect(gvc_source_stream, "notify::is-muted", + G_CALLBACK(notify_source_muted), this); + update_button_images(); +} \ No newline at end of file diff --git a/src/locker/plugin/volume.hpp b/src/locker/plugin/volume.hpp new file mode 100644 index 00000000..8fe65f72 --- /dev/null +++ b/src/locker/plugin/volume.hpp @@ -0,0 +1,42 @@ +#ifndef LOCKER_VOLUME_PLUGIN_HPP +#define LOCKER_VOLUME_PLUGIN_HPP + +#include +#include +#include +#include +#include +#include +#include "gvc-mixer-control.h" + +#include "../plugin.hpp" + +class WayfireLockerVolumePlugin : public WayfireLockerPlugin +{ + private: + GvcMixerControl *gvc_control; + GvcMixerStream *gvc_sink_stream = NULL; + GvcMixerStream *gvc_source_stream = NULL; + gulong notify_sink_muted_signal = 0; + gulong notify_source_muted_signal = 0; + void disconnect_gvc_stream_sink_signals(); + void disconnect_gvc_stream_source_signals(); + public: + WayfireLockerVolumePlugin(); + void add_output(int id, Gtk::Grid *grid) override; + void remove_output(int id) override; + bool should_enable() override; + void init() override; + bool enable; + void update_button_images(); + + /** Called when the default sink changes */ + void on_default_sink_changed(); + void on_default_source_changed(); + + std::unordered_map> sink_buttons; + std::unordered_map> source_buttons; + +}; + +#endif diff --git a/src/panel/widgets/volume.hpp b/src/panel/widgets/volume.hpp index 39d3dd25..53be598f 100644 --- a/src/panel/widgets/volume.hpp +++ b/src/panel/widgets/volume.hpp @@ -3,6 +3,7 @@ #include "../widget.hpp" #include "wf-popover.hpp" +#include #include #include #include From f812394a9c51f66e6af25d2ab6711a8ff2c6d1d6 Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 01:05:15 +0000 Subject: [PATCH 19/35] - uncrustify --- src/locker/plugin/fingerprint.cpp | 23 +++++------ src/locker/plugin/volume.cpp | 65 +++++++++++++++---------------- src/locker/plugin/volume.hpp | 6 +-- 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 9da937e0..e939cd0b 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -44,8 +44,7 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr & result) { auto manager_proxy = Gio::DBus::Proxy::create_finish(result); - try - { + try { auto default_device = manager_proxy->call_sync("GetDefaultDevice"); Glib::Variant item_path; default_device.get_child(item_path, 0); @@ -54,13 +53,12 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtrcall_sync("ListEnrolledFingers", nullptr, + auto reply = device_proxy->call_sync("ListEnrolledFingers", nullptr, Glib::Variant>::create(username)); Glib::Variant> array; reply.get_child(array, 0); @@ -137,23 +135,23 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_sync("Claim", nullptr, Glib::Variant>::create({username})); + device_proxy->call_sync("Claim", nullptr, + Glib::Variant>::create({username})); /* Start scanning in 5 seconds */ Glib::signal_timeout().connect_seconds( - [this] () + [this] () { this->start_fingerprint_scanning(); return G_SOURCE_REMOVE; }, 5); - }catch (Glib::Error e) /* TODO : Narrow down? */ + } catch (Glib::Error e) /* TODO : Narrow down? */ { - std::cout << "Fingerprint device already claimed, try in 5s"<claim_device(); return G_SOURCE_REMOVE; @@ -163,7 +161,6 @@ void WayfireLockerFingerprintPlugin::claim_device() /* Start fingerprint reader 5 seconds after start * This fixes an issue where the fingerprint reader * is a button which locks the screen */ - } void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() diff --git a/src/locker/plugin/volume.cpp b/src/locker/plugin/volume.cpp index f59c8515..31639cf6 100644 --- a/src/locker/plugin/volume.cpp +++ b/src/locker/plugin/volume.cpp @@ -19,7 +19,6 @@ static void default_source_changed(GvcMixerControl *gvc_control, plugin->on_default_source_changed(); } - static void notify_sink_muted(GvcMixerControl *gvc_control, guint id, gpointer user_data) { @@ -36,26 +35,28 @@ static void notify_source_muted(GvcMixerControl *gvc_control, void WayfireLockerVolumePlugin::update_button_images() { - if (gvc_sink_stream) { for (auto& it : sink_buttons) { - it.second->set_icon_name(gvc_mixer_stream_get_is_muted(gvc_sink_stream)?"audio-volume-muted-symbolic":"audio-volume-high-symbolic"); + it.second->set_icon_name(gvc_mixer_stream_get_is_muted( + gvc_sink_stream) ? "audio-volume-muted-symbolic" : "audio-volume-high-symbolic"); } } + if (gvc_source_stream) { for (auto& it : source_buttons) { - it.second->set_icon_name(gvc_mixer_stream_get_is_muted(gvc_source_stream)?"microphone-sensitivity-muted-symbolic":"microphone-sensitivity-high-symbolic"); + it.second->set_icon_name(gvc_mixer_stream_get_is_muted( + gvc_source_stream) ? "microphone-sensitivity-muted-symbolic" : "microphone-sensitivity-high-symbolic"); } } } WayfireLockerVolumePlugin::WayfireLockerVolumePlugin() { - enable=WfOption{"locker/volume_enable"}; + enable = WfOption{"locker/volume_enable"}; /* Setup gvc control */ gvc_control = gvc_mixer_control_new("Wayfire Volume Control"); g_signal_connect(gvc_control, @@ -63,7 +64,6 @@ WayfireLockerVolumePlugin::WayfireLockerVolumePlugin() g_signal_connect(gvc_control, "default-source-changed", G_CALLBACK(default_source_changed), this); gvc_mixer_control_open(gvc_control); - } bool WayfireLockerVolumePlugin::should_enable() @@ -76,39 +76,41 @@ void WayfireLockerVolumePlugin::add_output(int id, Gtk::Grid *grid) source_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); sink_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); auto source_button = source_buttons[id]; - auto sink_button = sink_buttons[id]; + auto sink_button = sink_buttons[id]; sink_button->add_css_class("volume-button"); source_button->add_css_class("mic-button"); - Gtk::Box *box = get_plugin_position(WfOption{"locker/volume_position"}, grid); + Gtk::Box *box = get_plugin_position(WfOption{"locker/volume_position"}, grid); auto inner_box = Gtk::Box(); inner_box.append(*source_button); inner_box.append(*sink_button); box->append(inner_box); - + sink_button->signal_clicked().connect( - [=] () { - if(!gvc_sink_stream) - { - return; - } - bool muted = gvc_mixer_stream_get_is_muted(gvc_sink_stream); - gvc_mixer_stream_change_is_muted(gvc_sink_stream, !muted); - gvc_mixer_stream_push_volume(gvc_sink_stream); + [=] () + { + if (!gvc_sink_stream) + { + return; } - ); + + bool muted = gvc_mixer_stream_get_is_muted(gvc_sink_stream); + gvc_mixer_stream_change_is_muted(gvc_sink_stream, !muted); + gvc_mixer_stream_push_volume(gvc_sink_stream); + }); source_button->signal_clicked().connect( - [=] () { - if(!gvc_source_stream) - { - return; - } - bool muted = gvc_mixer_stream_get_is_muted(gvc_source_stream); - gvc_mixer_stream_change_is_muted(gvc_source_stream, !muted); - gvc_mixer_stream_push_volume(gvc_source_stream); + [=] () + { + if (!gvc_source_stream) + { + return; } - ); + + bool muted = gvc_mixer_stream_get_is_muted(gvc_source_stream); + gvc_mixer_stream_change_is_muted(gvc_source_stream, !muted); + gvc_mixer_stream_push_volume(gvc_source_stream); + }); update_button_images(); } @@ -119,13 +121,10 @@ void WayfireLockerVolumePlugin::remove_output(int id) } void WayfireLockerVolumePlugin::init() -{ - -} +{} void WayfireLockerVolumePlugin::disconnect_gvc_stream_sink_signals() { - if (notify_sink_muted_signal) { g_signal_handler_disconnect(gvc_sink_stream, notify_sink_muted_signal); @@ -133,9 +132,9 @@ void WayfireLockerVolumePlugin::disconnect_gvc_stream_sink_signals() notify_sink_muted_signal = 0; } + void WayfireLockerVolumePlugin::disconnect_gvc_stream_source_signals() { - if (notify_source_muted_signal) { g_signal_handler_disconnect(gvc_source_stream, notify_source_muted_signal); @@ -174,4 +173,4 @@ void WayfireLockerVolumePlugin::on_default_source_changed() notify_source_muted_signal = g_signal_connect(gvc_source_stream, "notify::is-muted", G_CALLBACK(notify_source_muted), this); update_button_images(); -} \ No newline at end of file +} diff --git a/src/locker/plugin/volume.hpp b/src/locker/plugin/volume.hpp index 8fe65f72..e9547319 100644 --- a/src/locker/plugin/volume.hpp +++ b/src/locker/plugin/volume.hpp @@ -15,12 +15,13 @@ class WayfireLockerVolumePlugin : public WayfireLockerPlugin { private: GvcMixerControl *gvc_control; - GvcMixerStream *gvc_sink_stream = NULL; + GvcMixerStream *gvc_sink_stream = NULL; GvcMixerStream *gvc_source_stream = NULL; - gulong notify_sink_muted_signal = 0; + gulong notify_sink_muted_signal = 0; gulong notify_source_muted_signal = 0; void disconnect_gvc_stream_sink_signals(); void disconnect_gvc_stream_source_signals(); + public: WayfireLockerVolumePlugin(); void add_output(int id, Gtk::Grid *grid) override; @@ -36,7 +37,6 @@ class WayfireLockerVolumePlugin : public WayfireLockerPlugin std::unordered_map> sink_buttons; std::unordered_map> source_buttons; - }; #endif From 6349958444f82813fc54ea3e9415ae250deddfcc Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 08:49:17 +0000 Subject: [PATCH 20/35] - Fix center --- src/locker/locker.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 314d15d5..699f8300 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -106,6 +106,9 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) if (x == 0) { box->set_halign(Gtk::Align::START); + } else if (x == 1) + { + box->set_halign(Gtk::Align::CENTER); } else if (x == 2) { box->set_halign(Gtk::Align::END); @@ -114,6 +117,9 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) if (y == 0) { box->set_valign(Gtk::Align::START); + } else if (y == 1) + { + box->set_valign(Gtk::Align::CENTER); } else if (y == 2) { box->set_valign(Gtk::Align::END); From 6c2549d2d2427fe7b1f84dbcf558d016885937be Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 08:52:15 +0000 Subject: [PATCH 21/35] - uncrustify --- src/locker/locker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 699f8300..ed3b7c31 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -119,7 +119,7 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) box->set_valign(Gtk::Align::START); } else if (y == 1) { - box->set_valign(Gtk::Align::CENTER); + box->set_valign(Gtk::Align::CENTER); } else if (y == 2) { box->set_valign(Gtk::Align::END); From a6fe77ba7582116ff3bba36663b25f2bbb01fcb5 Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 09:55:50 +0000 Subject: [PATCH 22/35] - roll a custom grid widget to skip space wasted by homogenuous. --- src/locker/locker.cpp | 39 ++------------- src/locker/lockergrid.hpp | 82 +++++++++++++++++++++++++++++++ src/locker/plugin.hpp | 41 +--------------- src/locker/plugin/battery.cpp | 7 ++- src/locker/plugin/battery.hpp | 3 +- src/locker/plugin/clock.cpp | 6 +-- src/locker/plugin/clock.hpp | 3 +- src/locker/plugin/fingerprint.cpp | 9 ++-- src/locker/plugin/fingerprint.hpp | 3 +- src/locker/plugin/instant.cpp | 6 +-- src/locker/plugin/instant.hpp | 3 +- src/locker/plugin/password.cpp | 8 +-- src/locker/plugin/password.hpp | 3 +- src/locker/plugin/pin.cpp | 6 +-- src/locker/plugin/pin.hpp | 3 +- src/locker/plugin/volume.cpp | 6 +-- src/locker/plugin/volume.hpp | 3 +- 17 files changed, 125 insertions(+), 106 deletions(-) create mode 100644 src/locker/lockergrid.hpp diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index ed3b7c31..0a327834 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include @@ -16,6 +16,7 @@ #include "gtk4-session-lock.h" #include "gtkmm/enums.h" +#include "lockergrid.hpp" #include "plugin/battery.hpp" #include "plugin/clock.hpp" #include "plugin/instant.hpp" @@ -93,42 +94,10 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) /* Create lockscreen with a grid for contents */ auto window = new Gtk::Window(); window->add_css_class("wf-locker"); - auto grid = new Gtk::Grid(); + auto grid = new WayfireLockerGrid(); + window->set_child(*grid); grid->set_expand(true); - grid->set_column_homogeneous(true); - grid->set_row_homogeneous(true); - for (int x = 0; x < 3; x++) - { - for (int y = 0; y < 3; y++) - { - auto box = new Gtk::Box(); - if (x == 0) - { - box->set_halign(Gtk::Align::START); - } else if (x == 1) - { - box->set_halign(Gtk::Align::CENTER); - } else if (x == 2) - { - box->set_halign(Gtk::Align::END); - } - - if (y == 0) - { - box->set_valign(Gtk::Align::START); - } else if (y == 1) - { - box->set_valign(Gtk::Align::CENTER); - } else if (y == 2) - { - box->set_valign(Gtk::Align::END); - } - - box->set_orientation(Gtk::Orientation::VERTICAL); - grid->attach(*box, x, y); - } - } for (auto& it : plugins) { diff --git a/src/locker/lockergrid.hpp b/src/locker/lockergrid.hpp new file mode 100644 index 00000000..a557d1cc --- /dev/null +++ b/src/locker/lockergrid.hpp @@ -0,0 +1,82 @@ +#ifndef WF_LOCKER_GRID +#define WF_LOCKER_GRID +#include "gtkmm/enums.h" +#include +#include +#include +#include + +class WayfireLockerGrid : public Gtk::CenterBox{ + Gtk::CenterBox row1,row2,row3; + Gtk::Box box[9]; + public: + + /* Config string to box from grid */ + void attach(Gtk::Widget &widget, std::string pos_string) + { + if (pos_string == "top-left") + { + attach(widget, 0, 0); + } else if (pos_string == "top-center") + { + attach(widget, 1, 0); + } else if (pos_string == "top-right") + { + attach(widget, 2, 0); + } else if (pos_string == "center-left") + { + attach(widget, 0, 1); + } else if (pos_string == "center-center") + { + attach(widget, 1, 1); + } else if (pos_string == "center-right") + { + attach(widget, 2, 1); + } else if (pos_string == "bottom-left") + { + attach(widget, 0, 2); + } else if (pos_string == "bottom-center") + { + attach(widget, 1, 2); + } else if (pos_string == "bottom-right") + { + attach(widget, 2, 2); + } else { + throw std::exception(); + } + } + + void attach(Gtk::Widget &widget, int col, int row) + { + if(col > 2 || row > 2 || col < 0 || row < 0) + { + throw std::exception(); + } + box[col + (row*3)].append(widget); + } + + + + WayfireLockerGrid() + { + set_start_widget(row1); + set_center_widget(row2); + set_end_widget(row3); + set_orientation(Gtk::Orientation::VERTICAL); + row1.set_start_widget(box[0]); + row1.set_center_widget(box[1]); + row1.set_end_widget(box[2]); + row2.set_start_widget(box[3]); + row2.set_center_widget(box[4]); + row2.set_end_widget(box[5]); + row3.set_start_widget(box[6]); + row3.set_center_widget(box[7]); + row3.set_end_widget(box[8]); + for(int i = 0; i < 9; i ++) + { + box[i].set_orientation(Gtk::Orientation::VERTICAL); + } + } +}; + +#endif \ No newline at end of file diff --git a/src/locker/plugin.hpp b/src/locker/plugin.hpp index 3419a1a8..47eeb853 100644 --- a/src/locker/plugin.hpp +++ b/src/locker/plugin.hpp @@ -1,9 +1,7 @@ #ifndef LOCKER_PLUGIN_HPP #define LOCKER_PLUGIN_HPP -#include -#include - +#include "lockergrid.hpp" #define DEFAULT_PANEL_HEIGHT "48" #define DEFAULT_ICON_SIZE 32 @@ -21,45 +19,10 @@ class WayfireLockerPlugin * * We *do not* do config reloading. Sample config on construction or init, but not live */ virtual bool should_enable() = 0; - virtual void add_output(int id, Gtk::Grid *grid) = 0; + virtual void add_output(int id, WayfireLockerGrid *grid) = 0; virtual void remove_output(int id) = 0; virtual void init() = 0; virtual ~WayfireLockerPlugin() = default; - - /* Config string to box from grid */ - Gtk::Box *get_plugin_position(std::string pos_string, Gtk::Grid *grid) - { - if (pos_string == "top-left") - { - return (Gtk::Box*)grid->get_child_at(0, 0); - } else if (pos_string == "top-center") - { - return (Gtk::Box*)grid->get_child_at(1, 0); - } else if (pos_string == "top-right") - { - return (Gtk::Box*)grid->get_child_at(2, 0); - } else if (pos_string == "center-left") - { - return (Gtk::Box*)grid->get_child_at(0, 1); - } else if (pos_string == "center-center") - { - return (Gtk::Box*)grid->get_child_at(1, 1); - } else if (pos_string == "center-right") - { - return (Gtk::Box*)grid->get_child_at(2, 1); - } else if (pos_string == "bottom-left") - { - return (Gtk::Box*)grid->get_child_at(0, 2); - } else if (pos_string == "bottom-center") - { - return (Gtk::Box*)grid->get_child_at(1, 2); - } else if (pos_string == "bottom-right") - { - return (Gtk::Box*)grid->get_child_at(2, 2); - } - - return nullptr; - } }; #endif diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index 9a8c88f2..42726a6c 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -3,6 +3,7 @@ #include "gtkmm/image.h" #include "gtkmm/label.h" #include "gtkmm/box.h" +#include "lockergrid.hpp" #include "wf-option-wrap.hpp" #include #include "battery.hpp" @@ -92,7 +93,7 @@ void WayfireLockerBatteryPlugin::update_images() } } -void WayfireLockerBatteryPlugin::add_output(int id, Gtk::Grid *grid) +void WayfireLockerBatteryPlugin::add_output(int id, WayfireLockerGrid *grid) { Gtk::Grid *batt_grid = new Gtk::Grid(); labels.emplace(id, std::shared_ptr(new Gtk::Label())); @@ -117,9 +118,7 @@ void WayfireLockerBatteryPlugin::add_output(int id, Gtk::Grid *grid) batt_grid->attach(*label, 1, 0); batt_grid->attach(*subtext, 0, 1, 2, 1); - Gtk::Box *box = get_plugin_position(battery_position, grid); - - box->append(*batt_grid); + grid->attach(*batt_grid, (std::string)battery_position); update_details(); } diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index 641539ad..4723ac6e 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -10,6 +10,7 @@ #include #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" +#include "lockergrid.hpp" using DBusConnection = Glib::RefPtr; using DBusProxy = Glib::RefPtr; @@ -39,7 +40,7 @@ class WayfireLockerBatteryPlugin : public WayfireLockerPlugin public: WayfireLockerBatteryPlugin() {} - void add_output(int id, Gtk::Grid *grid) override; + void add_output(int id, WayfireLockerGrid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; diff --git a/src/locker/plugin/clock.cpp b/src/locker/plugin/clock.cpp index 87d25576..fa8583fa 100644 --- a/src/locker/plugin/clock.cpp +++ b/src/locker/plugin/clock.cpp @@ -2,6 +2,7 @@ #include #include #include "clock.hpp" +#include "lockergrid.hpp" bool WayfireLockerClockPlugin::should_enable() { @@ -18,15 +19,14 @@ void WayfireLockerClockPlugin::update_labels(std::string text) label_contents = text; } -void WayfireLockerClockPlugin::add_output(int id, Gtk::Grid *grid) +void WayfireLockerClockPlugin::add_output(int id, WayfireLockerGrid *grid) { labels.emplace(id, std::shared_ptr(new Gtk::Label())); auto label = labels[id]; label->add_css_class("clock"); label->set_label(label_contents); - Gtk::Box *box = get_plugin_position(WfOption{"locker/clock_position"}, grid); - box->append(*label); + grid->attach(*label, WfOption{"locker/clock_position"}); } void WayfireLockerClockPlugin::remove_output(int id) diff --git a/src/locker/plugin/clock.hpp b/src/locker/plugin/clock.hpp index 72397709..9f928f19 100644 --- a/src/locker/plugin/clock.hpp +++ b/src/locker/plugin/clock.hpp @@ -6,12 +6,13 @@ #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" +#include "lockergrid.hpp" class WayfireLockerClockPlugin : public WayfireLockerPlugin { public: WayfireLockerClockPlugin(); - void add_output(int id, Gtk::Grid *grid) override; + void add_output(int id, WayfireLockerGrid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index e939cd0b..9f80ffca 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -10,6 +10,7 @@ #include "../../util/wf-option-wrap.hpp" #include "glib.h" #include "locker.hpp" +#include "lockergrid.hpp" #include "fingerprint.hpp" @@ -187,7 +188,7 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() void WayfireLockerFingerprintPlugin::init() {} -void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid *grid) +void WayfireLockerFingerprintPlugin::add_output(int id, WayfireLockerGrid *grid) { labels.emplace(id, std::shared_ptr(new Gtk::Label())); images.emplace(id, std::shared_ptr(new Gtk::Image())); @@ -207,10 +208,8 @@ void WayfireLockerFingerprintPlugin::add_output(int id, Gtk::Grid *grid) image->add_css_class("fingerprint-icon"); label->add_css_class("fingerprint-text"); - Gtk::Box *box = get_plugin_position(WfOption{"locker/fingerprint_position"}, grid); - box->append(*image); - - box->append(*label); + grid->attach(*image,WfOption{"locker/fingerprint_position"}); + grid->attach(*label,WfOption{"locker/fingerprint_position"}); } void WayfireLockerFingerprintPlugin::remove_output(int id) diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 817a7fd0..fbf1d1fd 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -9,6 +9,7 @@ #include "../plugin.hpp" #include "giomm/dbusproxy.h" #include "glibmm/refptr.h" +#include "lockergrid.hpp" class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin { @@ -22,7 +23,7 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin void on_device_acquired(const Glib::RefPtr & result); void claim_device(); void start_fingerprint_scanning(); - void add_output(int id, Gtk::Grid *grid) override; + void add_output(int id, WayfireLockerGrid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; diff --git a/src/locker/plugin/instant.cpp b/src/locker/plugin/instant.cpp index e395896e..5e526fdf 100644 --- a/src/locker/plugin/instant.cpp +++ b/src/locker/plugin/instant.cpp @@ -2,6 +2,7 @@ #include #include #include "../locker.hpp" +#include "lockergrid.hpp" #include "instant.hpp" bool WayfireLockerInstantPlugin::should_enable() @@ -9,15 +10,14 @@ bool WayfireLockerInstantPlugin::should_enable() return (bool)enable; } -void WayfireLockerInstantPlugin::add_output(int id, Gtk::Grid *grid) +void WayfireLockerInstantPlugin::add_output(int id, WayfireLockerGrid *grid) { buttons.emplace(id, std::shared_ptr(new Gtk::Button())); auto button = buttons[id]; button->set_label("Press to unlock"); button->add_css_class("instant-unlock"); - Gtk::Box *box = get_plugin_position(WfOption{"locker/instant_unlock_position"}, grid); - box->append(*button); + grid->attach(*button, WfOption{"locker/instant_unlock_position"}); button->signal_clicked().connect([] () { diff --git a/src/locker/plugin/instant.hpp b/src/locker/plugin/instant.hpp index ce5c5b6d..e5c59eae 100644 --- a/src/locker/plugin/instant.hpp +++ b/src/locker/plugin/instant.hpp @@ -5,13 +5,14 @@ #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" +#include "lockergrid.hpp" class WayfireLockerInstantPlugin : public WayfireLockerPlugin { public: WayfireLockerInstantPlugin() {} - void add_output(int id, Gtk::Grid *grid) override; + void add_output(int id, WayfireLockerGrid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; diff --git a/src/locker/plugin/password.cpp b/src/locker/plugin/password.cpp index a5fb3dfd..5bfff15c 100644 --- a/src/locker/plugin/password.cpp +++ b/src/locker/plugin/password.cpp @@ -5,6 +5,7 @@ #include "gtkmm/entry.h" #include "gtkmm/label.h" #include "locker.hpp" +#include "lockergrid.hpp" #include #include @@ -35,7 +36,7 @@ void WayfireLockerPasswordPlugin::blank_passwords() } } -void WayfireLockerPasswordPlugin::add_output(int id, Gtk::Grid *grid) +void WayfireLockerPasswordPlugin::add_output(int id, WayfireLockerGrid *grid) { labels.emplace(id, std::shared_ptr(new Gtk::Label())); entries.emplace(id, std::shared_ptr(new Gtk::Entry)); @@ -56,9 +57,8 @@ void WayfireLockerPasswordPlugin::add_output(int id, Gtk::Grid *grid) } }, true); /* Add to window */ - Gtk::Box *box = get_plugin_position(WfOption{"locker/password_position"}, grid); - box->append(*entry); - box->append(*label); + grid->attach(*entry, WfOption{"locker/password_position"}); + grid->attach(*label, WfOption{"locker/password_position"}); } void WayfireLockerPasswordPlugin::remove_output(int id) diff --git a/src/locker/plugin/password.hpp b/src/locker/plugin/password.hpp index 88e5f4bb..f049abfe 100644 --- a/src/locker/plugin/password.hpp +++ b/src/locker/plugin/password.hpp @@ -6,6 +6,7 @@ #include #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" +#include "lockergrid.hpp" int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); @@ -14,7 +15,7 @@ class WayfireLockerPasswordPlugin : public WayfireLockerPlugin { public: WayfireLockerPasswordPlugin(); - void add_output(int id, Gtk::Grid *grid) override; + void add_output(int id, WayfireLockerGrid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index 983a2755..f7b7c3d7 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -12,6 +12,7 @@ #include "../../util/wf-option-wrap.hpp" #include "locker.hpp" +#include "lockergrid.hpp" #include "pin.hpp" @@ -145,14 +146,13 @@ bool WayfireLockerPinPlugin::should_enable() return enable; } -void WayfireLockerPinPlugin::add_output(int id, Gtk::Grid *grid) +void WayfireLockerPinPlugin::add_output(int id, WayfireLockerGrid *grid) { pinpads.emplace(id, new PinPad()); auto pinpad = pinpads[id]; pinpad->add_css_class("pinpad"); pinpad->init(); - Gtk::Box *box = get_plugin_position(WfOption{"locker/pin_position"}, grid); - box->append(*pinpad); + grid->attach(*pinpad, WfOption{"locker/pin_position"}); update_labels(); /* Update all to set this one? maybe overkill */ } diff --git a/src/locker/plugin/pin.hpp b/src/locker/plugin/pin.hpp index 1df67041..e5bfcd11 100644 --- a/src/locker/plugin/pin.hpp +++ b/src/locker/plugin/pin.hpp @@ -8,6 +8,7 @@ #include "../plugin.hpp" #include "glibmm/refptr.h" +#include "lockergrid.hpp" /* Rather than keep an unordered list for each widget, put them together */ class WayfireLockerPinPlugin; @@ -27,7 +28,7 @@ class WayfireLockerPinPlugin : public WayfireLockerPlugin { public: WayfireLockerPinPlugin(); - void add_output(int id, Gtk::Grid *grid) override; + void add_output(int id, WayfireLockerGrid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; diff --git a/src/locker/plugin/volume.cpp b/src/locker/plugin/volume.cpp index 31639cf6..8ea712d9 100644 --- a/src/locker/plugin/volume.cpp +++ b/src/locker/plugin/volume.cpp @@ -2,6 +2,7 @@ #include #include #include "clock.hpp" +#include "lockergrid.hpp" #include "volume.hpp" @@ -71,7 +72,7 @@ bool WayfireLockerVolumePlugin::should_enable() return (bool)enable; } -void WayfireLockerVolumePlugin::add_output(int id, Gtk::Grid *grid) +void WayfireLockerVolumePlugin::add_output(int id, WayfireLockerGrid *grid) { source_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); sink_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); @@ -81,11 +82,10 @@ void WayfireLockerVolumePlugin::add_output(int id, Gtk::Grid *grid) sink_button->add_css_class("volume-button"); source_button->add_css_class("mic-button"); - Gtk::Box *box = get_plugin_position(WfOption{"locker/volume_position"}, grid); auto inner_box = Gtk::Box(); inner_box.append(*source_button); inner_box.append(*sink_button); - box->append(inner_box); + grid->attach(inner_box, WfOption{"locker/volume_position"}); sink_button->signal_clicked().connect( [=] () diff --git a/src/locker/plugin/volume.hpp b/src/locker/plugin/volume.hpp index e9547319..a5df399d 100644 --- a/src/locker/plugin/volume.hpp +++ b/src/locker/plugin/volume.hpp @@ -10,6 +10,7 @@ #include "gvc-mixer-control.h" #include "../plugin.hpp" +#include "lockergrid.hpp" class WayfireLockerVolumePlugin : public WayfireLockerPlugin { @@ -24,7 +25,7 @@ class WayfireLockerVolumePlugin : public WayfireLockerPlugin public: WayfireLockerVolumePlugin(); - void add_output(int id, Gtk::Grid *grid) override; + void add_output(int id, WayfireLockerGrid *grid) override; void remove_output(int id) override; bool should_enable() override; void init() override; From 5a7cbabfab188a8eecaecfae3b620ef390df6704 Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 10:10:53 +0000 Subject: [PATCH 23/35] - uncrustify --- src/locker/lockergrid.hpp | 23 ++++++++++++----------- src/locker/plugin/fingerprint.cpp | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/locker/lockergrid.hpp b/src/locker/lockergrid.hpp index a557d1cc..ea17ca4f 100644 --- a/src/locker/lockergrid.hpp +++ b/src/locker/lockergrid.hpp @@ -6,13 +6,14 @@ #include #include -class WayfireLockerGrid : public Gtk::CenterBox{ - Gtk::CenterBox row1,row2,row3; +class WayfireLockerGrid : public Gtk::CenterBox +{ + Gtk::CenterBox row1, row2, row3; Gtk::Box box[9]; - public: - + + public: /* Config string to box from grid */ - void attach(Gtk::Widget &widget, std::string pos_string) + void attach(Gtk::Widget & widget, std::string pos_string) { if (pos_string == "top-left") { @@ -41,22 +42,22 @@ class WayfireLockerGrid : public Gtk::CenterBox{ } else if (pos_string == "bottom-right") { attach(widget, 2, 2); - } else { + } else + { throw std::exception(); } } - void attach(Gtk::Widget &widget, int col, int row) + void attach(Gtk::Widget & widget, int col, int row) { - if(col > 2 || row > 2 || col < 0 || row < 0) + if ((col > 2) || (row > 2) || (col < 0) || (row < 0)) { throw std::exception(); } - box[col + (row*3)].append(widget); + + box[col + (row * 3)].append(widget); } - - WayfireLockerGrid() { set_start_widget(row1); diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 9f80ffca..b232eca7 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -208,8 +208,8 @@ void WayfireLockerFingerprintPlugin::add_output(int id, WayfireLockerGrid *grid) image->add_css_class("fingerprint-icon"); label->add_css_class("fingerprint-text"); - grid->attach(*image,WfOption{"locker/fingerprint_position"}); - grid->attach(*label,WfOption{"locker/fingerprint_position"}); + grid->attach(*image, WfOption{"locker/fingerprint_position"}); + grid->attach(*label, WfOption{"locker/fingerprint_position"}); } void WayfireLockerFingerprintPlugin::remove_output(int id) From 036690666278b2c8b75b1da615d75e204a145f20 Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 10:13:40 +0000 Subject: [PATCH 24/35] - uncrust --- src/locker/lockergrid.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locker/lockergrid.hpp b/src/locker/lockergrid.hpp index ea17ca4f..6f8f58f6 100644 --- a/src/locker/lockergrid.hpp +++ b/src/locker/lockergrid.hpp @@ -10,7 +10,7 @@ class WayfireLockerGrid : public Gtk::CenterBox { Gtk::CenterBox row1, row2, row3; Gtk::Box box[9]; - + public: /* Config string to box from grid */ void attach(Gtk::Widget & widget, std::string pos_string) @@ -54,7 +54,7 @@ class WayfireLockerGrid : public Gtk::CenterBox { throw std::exception(); } - + box[col + (row * 3)].append(widget); } @@ -73,7 +73,7 @@ class WayfireLockerGrid : public Gtk::CenterBox row3.set_start_widget(box[6]); row3.set_center_widget(box[7]); row3.set_end_widget(box[8]); - for(int i = 0; i < 9; i ++) + for (int i = 0; i < 9; i++) { box[i].set_orientation(Gtk::Orientation::VERTICAL); } From 0a5c1562fccaf7e6e9765aefe5297a9a60f23a3a Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 10:15:13 +0000 Subject: [PATCH 25/35] - uncrust --- src/locker/lockergrid.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locker/lockergrid.hpp b/src/locker/lockergrid.hpp index 6f8f58f6..dd0233f3 100644 --- a/src/locker/lockergrid.hpp +++ b/src/locker/lockergrid.hpp @@ -80,4 +80,4 @@ class WayfireLockerGrid : public Gtk::CenterBox } }; -#endif \ No newline at end of file +#endif From 10c6c2945468c4960823b9eaa01c366ad6e58793 Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 10:43:18 +0000 Subject: [PATCH 26/35] - clean includes --- src/locker/locker.cpp | 20 +++++++++----------- src/locker/locker.hpp | 7 ++++--- src/locker/lockergrid.hpp | 1 - src/locker/plugin/battery.cpp | 8 +++----- src/locker/plugin/battery.hpp | 8 ++++---- src/locker/plugin/clock.cpp | 3 ++- src/locker/plugin/fingerprint.cpp | 13 +++++++------ src/locker/plugin/fingerprint.hpp | 8 ++++---- src/locker/plugin/instant.cpp | 1 + src/locker/plugin/password.cpp | 10 ++++------ src/locker/plugin/password.hpp | 1 + src/locker/plugin/pin.cpp | 13 +++++++------ src/locker/plugin/pin.hpp | 4 ++-- src/locker/plugin/volume.cpp | 4 ++-- src/locker/plugin/volume.hpp | 6 +++--- 15 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 0a327834..c15576c1 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -1,21 +1,18 @@ + +#include #include +#include #include #include #include #include #include +#include #include +#include +#include -#include - -#include -#include "locker.hpp" - -#include "gdkmm/monitor.h" -#include "glibmm/miscutils.h" -#include "gtk4-session-lock.h" -#include "gtkmm/enums.h" - +#include "css-config.hpp" #include "lockergrid.hpp" #include "plugin/battery.hpp" #include "plugin/clock.hpp" @@ -25,7 +22,8 @@ #include "plugin/fingerprint.hpp" #include "plugin/volume.hpp" #include "wf-shell-app.hpp" -#include +#include "locker.hpp" + WayfireLockerApp::~WayfireLockerApp() {} diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index e5a4e375..69876efc 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -1,13 +1,14 @@ #ifndef WF_LOCKER_HPP #define WF_LOCKER_HPP -#include "plugin.hpp" -#include "wf-shell-app.hpp" #include -#include #include #include #include +#include + +#include "wf-shell-app.hpp" +#include "plugin.hpp" using Plugin = std::shared_ptr; void on_session_locked_c(GtkSessionLockInstance *lock, void *data); diff --git a/src/locker/lockergrid.hpp b/src/locker/lockergrid.hpp index dd0233f3..139dbb88 100644 --- a/src/locker/lockergrid.hpp +++ b/src/locker/lockergrid.hpp @@ -1,6 +1,5 @@ #ifndef WF_LOCKER_GRID #define WF_LOCKER_GRID -#include "gtkmm/enums.h" #include #include #include diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index 42726a6c..8f8017e0 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -1,11 +1,9 @@ #include +#include +#include +#include -#include "gtkmm/image.h" -#include "gtkmm/label.h" -#include "gtkmm/box.h" #include "lockergrid.hpp" -#include "wf-option-wrap.hpp" -#include #include "battery.hpp" diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index 4723ac6e..f2ac41e7 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -1,13 +1,13 @@ #ifndef LOCKER_BATTERY_PLUGIN_HPP #define LOCKER_BATTERY_PLUGIN_HPP +#include +#include +#include #include #include #include - #include -#include -#include -#include + #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" #include "lockergrid.hpp" diff --git a/src/locker/plugin/clock.cpp b/src/locker/plugin/clock.cpp index fa8583fa..64158452 100644 --- a/src/locker/plugin/clock.cpp +++ b/src/locker/plugin/clock.cpp @@ -1,8 +1,9 @@ #include #include #include -#include "clock.hpp" + #include "lockergrid.hpp" +#include "clock.hpp" bool WayfireLockerClockPlugin::should_enable() { diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index b232eca7..5b4552ed 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -1,14 +1,15 @@ +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include +#include + #include "../../util/wf-option-wrap.hpp" -#include "glib.h" #include "locker.hpp" #include "lockergrid.hpp" #include "fingerprint.hpp" @@ -54,7 +55,7 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtrstart_fingerprint_scanning(); return G_SOURCE_REMOVE; }, 5); - } catch (Glib::Error e) /* TODO : Narrow down? */ + } catch (Glib::Error &e) /* TODO : Narrow down? */ { std::cout << "Fingerprint device already claimed, try in 5s" << std::endl; update_labels("Fingerprint reader busy..."); diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index fbf1d1fd..cc06995c 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -1,15 +1,15 @@ #ifndef LOCKER_FINGERPRINT_PLUGIN_HPP #define LOCKER_FINGERPRINT_PLUGIN_HPP +#include #include #include -#include #include +#include +#include -#include "../plugin.hpp" -#include "giomm/dbusproxy.h" -#include "glibmm/refptr.h" #include "lockergrid.hpp" +#include "../plugin.hpp" class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin { diff --git a/src/locker/plugin/instant.cpp b/src/locker/plugin/instant.cpp index 5e526fdf..2dda575f 100644 --- a/src/locker/plugin/instant.cpp +++ b/src/locker/plugin/instant.cpp @@ -1,6 +1,7 @@ #include #include #include + #include "../locker.hpp" #include "lockergrid.hpp" #include "instant.hpp" diff --git a/src/locker/plugin/password.cpp b/src/locker/plugin/password.cpp index 5bfff15c..2fa94528 100644 --- a/src/locker/plugin/password.cpp +++ b/src/locker/plugin/password.cpp @@ -1,17 +1,15 @@ +#include #include #include -#include "password.hpp" -#include "gtkmm/box.h" #include "gtkmm/entry.h" #include "gtkmm/label.h" -#include "locker.hpp" -#include "lockergrid.hpp" - #include #include #include -#include +#include "locker.hpp" +#include "lockergrid.hpp" +#include "password.hpp" bool WayfireLockerPasswordPlugin::should_enable() { diff --git a/src/locker/plugin/password.hpp b/src/locker/plugin/password.hpp index f049abfe..cfa2cddf 100644 --- a/src/locker/plugin/password.hpp +++ b/src/locker/plugin/password.hpp @@ -4,6 +4,7 @@ #include #include #include + #include "../plugin.hpp" #include "../../util/wf-option-wrap.hpp" #include "lockergrid.hpp" diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index f7b7c3d7..3323e161 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -1,14 +1,15 @@ +#include +#include +#include +#include +#include +#include #include #include -#include #include #include -#include -#include #include -#include -#include -#include + #include "../../util/wf-option-wrap.hpp" #include "locker.hpp" diff --git a/src/locker/plugin/pin.hpp b/src/locker/plugin/pin.hpp index e5bfcd11..e27ac9af 100644 --- a/src/locker/plugin/pin.hpp +++ b/src/locker/plugin/pin.hpp @@ -1,13 +1,13 @@ #ifndef LOCKER_PIN_PLUGIN_HPP #define LOCKER_PIN_PLUGIN_HPP +#include #include #include #include -#include +#include #include "../plugin.hpp" -#include "glibmm/refptr.h" #include "lockergrid.hpp" /* Rather than keep an unordered list for each widget, put them together */ diff --git a/src/locker/plugin/volume.cpp b/src/locker/plugin/volume.cpp index 8ea712d9..f188b19a 100644 --- a/src/locker/plugin/volume.cpp +++ b/src/locker/plugin/volume.cpp @@ -1,10 +1,10 @@ #include #include #include -#include "clock.hpp" -#include "lockergrid.hpp" +#include "lockergrid.hpp" #include "volume.hpp" +#include "../../util/wf-option-wrap.hpp" static void default_sink_changed(GvcMixerControl *gvc_control, guint id, gpointer user_data) diff --git a/src/locker/plugin/volume.hpp b/src/locker/plugin/volume.hpp index a5df399d..4ebf1dc6 100644 --- a/src/locker/plugin/volume.hpp +++ b/src/locker/plugin/volume.hpp @@ -1,14 +1,14 @@ #ifndef LOCKER_VOLUME_PLUGIN_HPP #define LOCKER_VOLUME_PLUGIN_HPP +#include +#include #include #include #include -#include -#include #include -#include "gvc-mixer-control.h" +#include "gvc-mixer-control.h" #include "../plugin.hpp" #include "lockergrid.hpp" From e9efd462d7b7acfb403871fe37c9716fc7087026 Mon Sep 17 00:00:00 2001 From: trigg Date: Mon, 19 Jan 2026 10:57:29 +0000 Subject: [PATCH 27/35] - uncrust --- src/locker/plugin/fingerprint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 5b4552ed..a14a26c1 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -55,7 +55,7 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtrstart_fingerprint_scanning(); return G_SOURCE_REMOVE; }, 5); - } catch (Glib::Error &e) /* TODO : Narrow down? */ + } catch (Glib::Error & e) /* TODO : Narrow down? */ { std::cout << "Fingerprint device already claimed, try in 5s" << std::endl; update_labels("Fingerprint reader busy..."); From bea6b60ab765c0a6d2ded13159b3afcfa850df90 Mon Sep 17 00:00:00 2001 From: trigg Date: Tue, 20 Jan 2026 03:28:01 +0000 Subject: [PATCH 28/35] - Fix fingerprint reader stopping after an extra suspend and resume - Implemented MPRIS on dbus to allow media control plugin --- data/css/default.css | 7 + metadata/locker.xml | 61 +++++ src/locker/locker.cpp | 3 +- src/locker/lockergrid.hpp | 20 ++ src/locker/meson.build | 3 +- src/locker/plugin/fingerprint.cpp | 14 +- src/locker/plugin/mpris.cpp | 386 ++++++++++++++++++++++++++++++ src/locker/plugin/mpris.hpp | 73 ++++++ 8 files changed, 564 insertions(+), 3 deletions(-) create mode 100644 src/locker/plugin/mpris.cpp create mode 100644 src/locker/plugin/mpris.hpp diff --git a/data/css/default.css b/data/css/default.css index eed40763..08dcc555 100644 --- a/data/css/default.css +++ b/data/css/default.css @@ -146,6 +146,13 @@ animation-fill-mode: forwards; } +revealer.wf-locker { + border: 2px solid rgba(128,128,128,0.1); +} +.wf-locker .mpris image.albumart { + -gtk-icon-size:96px; +} + @keyframes embiggen { to { -gtk-icon-size: 64px; diff --git a/metadata/locker.xml b/metadata/locker.xml index 201dfb37..1d016024 100644 --- a/metadata/locker.xml +++ b/metadata/locker.xml @@ -222,6 +222,67 @@ + <_short>Now Playing + + + + + + <_short>Battery @@ -156,7 +156,7 @@ bottom-right <_name>Bottom Right - center-center + center-right + + + <_short>User + + + @@ -279,7 +329,7 @@ bottom-right <_name>Bottom Right - bottom-center + bottom-right @@ -341,15 +391,15 @@ bottom-right <_name>Bottom Right - bottom-center + top-left