From cd8575d6c56fc6b7d63273a7ad283adb8390e1c8 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 18 Jan 2026 17:01:51 +0000 Subject: [PATCH 01/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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/67] - 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 + <_short>Password diff --git a/src/background/background.cpp b/src/background/background.cpp index 759a54d7..bd521e39 100644 --- a/src/background/background.cpp +++ b/src/background/background.cpp @@ -16,6 +16,7 @@ #include #include "background.hpp" +#include "giomm/application.h" @@ -631,6 +632,7 @@ class WayfireBackgroundApp : public WayfireShellApp { WayfireShellApp::instance = std::make_unique(); + instance->init_app(); g_unix_signal_add(SIGUSR1, sigusr1_handler, (void*)instance.get()); instance->run(argc, argv); } @@ -655,6 +657,16 @@ class WayfireBackgroundApp : public WayfireShellApp return TRUE; } + + std::string get_application_name() override + { + return "org.wayfire.background"; + } + + Gio::Application::Flags get_extra_application_flags() override + { + return Gio::Application::Flags::NON_UNIQUE; + } }; int main(int argc, char **argv) diff --git a/src/dock/dock-app.cpp b/src/dock/dock-app.cpp index dc6e6d9b..c10f0164 100644 --- a/src/dock/dock-app.cpp +++ b/src/dock/dock-app.cpp @@ -1,4 +1,5 @@ #include "dock.hpp" +#include "giomm/application.h" #include "toplevel.hpp" #include "toplevel-icon.hpp" #include @@ -148,9 +149,20 @@ void WfDockApp::create(int argc, char **argv) } instance = std::unique_ptr{new WfDockApp()}; + instance->init_app(); instance->run(argc, argv); } +std::string WfDockApp::get_application_name() +{ + return "org.wayfire.dock"; +} + +Gio::Application::Flags WfDockApp::get_extra_application_flags() +{ + return Gio::Application::Flags::NON_UNIQUE; +} + WfDockApp::WfDockApp() : WayfireShellApp(), priv(new WfDockApp::impl()) {} WfDockApp::~WfDockApp() = default; diff --git a/src/dock/dock.hpp b/src/dock/dock.hpp index 012c8e80..e2ba5e86 100644 --- a/src/dock/dock.hpp +++ b/src/dock/dock.hpp @@ -4,6 +4,7 @@ #include #include +#include "giomm/application.h" #include "wf-shell-app.hpp" #include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h" #include @@ -38,6 +39,8 @@ class WfDockApp : public WayfireShellApp * call to run() */ static void create(int argc, char **argv); virtual ~WfDockApp(); + std::string get_application_name() override; + Gio::Application::Flags get_extra_application_flags() override; void on_activate() override; void handle_new_output(WayfireOutput *output) override; diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 2b4d32e8..ae9d425f 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -12,6 +12,7 @@ #include #include "css-config.hpp" +#include "giomm/application.h" #include "lockergrid.hpp" #include "plugin/battery.hpp" #include "plugin/clock.hpp" @@ -22,16 +23,55 @@ #include "plugin/user.hpp" #include "plugin/volume.hpp" #include "plugin/mpris.hpp" +#include "wf-option-wrap.hpp" #include "wf-shell-app.hpp" #include "locker.hpp" +Gio::Application::Flags WayfireLockerApp::get_extra_application_flags() +{ + return Gio::Application::Flags::NONE; +} + +std::string WayfireLockerApp::get_application_name() +{ + return "org.wayfire.locker"; +} + +WayfireLockerApp::WayfireLockerApp() +{} WayfireLockerApp::~WayfireLockerApp() {} +void WayfireLockerApp::perform_lock() +{ + if (is_debug()) + { + if(!m_is_locked) + { + on_monitor_present(nullptr); + } + } else + { + /* Demand the session be locked */ + gtk_session_lock_instance_lock(lock); + } +} + void WayfireLockerApp::on_activate() { + if (activated) + { + if (!m_is_locked) + { + perform_lock(); + } + return; + } + std::cout << "Starting App" << std::endl; WayfireShellApp::on_activate(); + exit_on_unlock = WfOption{"locker/exit_on_unlock"}; + auto debug = Glib::getenv("WF_LOCKER_DEBUG"); if (debug == "1") { @@ -72,20 +112,48 @@ void WayfireLockerApp::on_activate() for (auto& it : plugins) { - if (it.second->should_enable()) + Plugin plugin = it.second; + if (plugin->enable) { it.second->init(); } + plugin->enable.set_callback( + [plugin, this] () { + if (plugin->enable) + { + std::cout << "Plugin enable" << std::endl; + plugin->init(); + for(auto &it : window_list) + { + std::cout << "Adding to window"<add_output(id, grid_list[id]); + } + } else { + std::cout << "Plugin disable" << std::endl; + for(auto &it : window_list) + { + std::cout << "Removing from window"<remove_output(id, grid_list[id]); + } + plugin->deinit(); + } + } + ); + plugin->position.set_callback( + [this, plugin] () { + for(auto &it : grid_list) + { + int id = it.first; + auto grid = it.second; + plugin->remove_output(id, grid); + plugin->add_output(id, grid); + } + } + ); } - - if (is_debug()) - { - on_monitor_present(nullptr); - } else - { - /* Demand the session be locked */ - gtk_session_lock_instance_lock(lock); - } + perform_lock(); } /* A new monitor has been added to the lockscreen */ @@ -96,14 +164,17 @@ 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 WayfireLockerGrid(); + auto grid = std::shared_ptr(new WayfireLockerGrid()); window->set_child(*grid); grid->set_expand(true); + grid_list.emplace(id, grid); + window_list.emplace(id, window); for (auto& it : plugins) { - if (it.second->should_enable()) + Plugin plugin = it.second; + if (plugin->enable) { it.second->add_output(id, grid); } @@ -113,13 +184,26 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) { for (auto& it : plugins) { - it.second->remove_output(id); + Plugin plugin = it.second; + if (plugin->enable) + { + plugin->remove_output(id, grid_list[id]); + } + } + if (m_is_debug) + { + m_is_locked = false; + if (exit_on_unlock) + { + exit(0); + } } return false; }, false); if (is_debug()) { + m_is_locked = true; window->present(); } else { @@ -128,14 +212,24 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) } /* Called on any successful auth to unlock & end locker */ -void WayfireLockerApp::unlock() +void WayfireLockerApp::perform_unlock() { - if (is_debug()) + if (m_is_debug) { - exit(0); + /* We need to manually close in debug mode */ + for(auto &it : window_list) + { + it.second->close(); + } + if (WayfireLockerApp::get().exit_on_unlock) + { + exit(0); + } + } else + { + gtk_session_lock_instance_unlock(lock); } - - gtk_session_lock_instance_unlock(lock); + window_list.clear(); } void WayfireLockerApp::create(int argc, char **argv) @@ -146,9 +240,20 @@ void WayfireLockerApp::create(int argc, char **argv) } instance = std::unique_ptr(new WayfireLockerApp{}); + instance->init_app(); instance->run(argc, argv); } +bool WayfireLockerApp::is_locked() +{ + return m_is_locked; +} + +void WayfireLockerApp::set_is_locked(bool locked) +{ + m_is_locked = locked; +} + /* Starting point */ int main(int argc, char **argv) { @@ -166,24 +271,32 @@ int main(int argc, char **argv) /* lock session calllbacks */ void on_session_locked_c(GtkSessionLockInstance *lock, void *data) { + WayfireLockerApp::get().set_is_locked(true); std::cout << "Session locked" << std::endl; } void on_session_lock_failed_c(GtkSessionLockInstance *lock, void *data) { + WayfireLockerApp::get().set_is_locked(false); std::cout << "Session lock failed" << std::endl; - exit(0); + if (WayfireLockerApp::get().exit_on_unlock) + { + exit(0); + } } void on_session_unlocked_c(GtkSessionLockInstance *lock, void *data) { + WayfireLockerApp::get().set_is_locked(false); std::cout << "Session unlocked" << std::endl; - // Exiting here causes wf to lock up - Glib::signal_timeout().connect_seconds([] () -> bool + if (WayfireLockerApp::get().exit_on_unlock) { - exit(0); - return 0; - }, 1); + // Exiting too early causes a lock-out + Glib::signal_timeout().connect_seconds([] () -> bool + { + exit(0); + },1); + } } void on_monitor_present_c(GtkSessionLockInstance *lock, GdkMonitor *monitor, void *data) diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index f0948fd2..c207e18c 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -26,10 +26,15 @@ class WayfireLockerApp : public WayfireShellApp std::map plugins = {}; bool m_is_debug = false; + bool m_is_locked = false; int window_id_count = 0; + + std::map> window_list; + std::map> grid_list; std::vector> css_rules; + public: using WayfireShellApp::WayfireShellApp; static void create(int argc, char **argv); @@ -37,6 +42,8 @@ class WayfireLockerApp : public WayfireShellApp { return (WayfireLockerApp&)WayfireShellApp::get(); } + Gio::Application::Flags get_extra_application_flags(); + std::string get_application_name() override; /* Starts the program. get() is valid afterward the first (and the only) * call to create() */ @@ -47,10 +54,19 @@ class WayfireLockerApp : public WayfireShellApp return m_is_debug; } + bool exit_on_unlock = true; + + + bool is_locked(); + void set_is_locked(bool locked); + WayfireLockerApp(); ~WayfireLockerApp(); Plugin get_plugin(std::string name); - void unlock(); + + /* Give commands to compositor about lock state, or emulate them*/ + void perform_unlock(); + void perform_lock(); private: }; diff --git a/src/locker/lockergrid.hpp b/src/locker/lockergrid.hpp index 089d456d..fed39103 100644 --- a/src/locker/lockergrid.hpp +++ b/src/locker/lockergrid.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -10,6 +11,19 @@ class WayfireLockerGrid : public Gtk::CenterBox Gtk::Box box[9]; public: + + void remove(Gtk::Widget & widget) + { + for (int count = 0; count < 9; count++) + { + auto list = box[count].get_children(); + int children = std::count(list.begin(), list.end(), &widget); + if (children == 1) + { + box[count].remove(widget); + } + } + } /* Config string to box from grid */ void attach(Gtk::Widget & widget, std::string pos_string) { diff --git a/src/locker/plugin.hpp b/src/locker/plugin.hpp index 58c644f5..e9f76d5c 100644 --- a/src/locker/plugin.hpp +++ b/src/locker/plugin.hpp @@ -1,4 +1,5 @@ #pragma once +#include "wf-option-wrap.hpp" #include "lockergrid.hpp" #define DEFAULT_PANEL_HEIGHT "48" #define DEFAULT_ICON_SIZE 32 @@ -12,13 +13,15 @@ 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, WayfireLockerGrid *grid) = 0; - virtual void remove_output(int id) = 0; + WayfireLockerPlugin(std::string option_name, std::string position_name): + enable(WfOption{option_name}), + position(WfOption{position_name}) + {}; + WfOption enable; + WfOption position; + virtual void add_output(int id, std::shared_ptr grid) = 0; + virtual void remove_output(int id, std::shared_ptr grid) = 0; virtual void init() = 0; + virtual void deinit() = 0; virtual ~WayfireLockerPlugin() = default; }; diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index 8f8017e0..3dbe9e45 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -60,11 +60,6 @@ static std::string uint_to_time(int64_t time) 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) @@ -91,12 +86,13 @@ void WayfireLockerBatteryPlugin::update_images() } } -void WayfireLockerBatteryPlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerBatteryPlugin::add_output(int id, std::shared_ptr grid) { - Gtk::Grid *batt_grid = new Gtk::Grid(); + grids.emplace(id, std::shared_ptr(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 batt_grid = grids[id]; auto label = labels[id]; auto subtext = subtexts[id]; auto image = images[id]; @@ -116,14 +112,18 @@ void WayfireLockerBatteryPlugin::add_output(int id, WayfireLockerGrid *grid) batt_grid->attach(*label, 1, 0); batt_grid->attach(*subtext, 0, 1, 2, 1); - grid->attach(*batt_grid, (std::string)battery_position); + grid->attach(*batt_grid, (std::string)position); update_details(); } -void WayfireLockerBatteryPlugin::remove_output(int id) +void WayfireLockerBatteryPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*grids[id]); + grids.erase(id); labels.erase(id); + subtexts.erase(id); + images.erase(id); } void WayfireLockerBatteryPlugin::init() @@ -134,6 +134,13 @@ void WayfireLockerBatteryPlugin::init() } } +void WayfireLockerBatteryPlugin::deinit() +{ + // TODO Clean up. + + +} + bool WayfireLockerBatteryPlugin::setup_dbus() { auto cancellable = Gio::Cancellable::create(); @@ -285,3 +292,7 @@ void WayfireLockerBatteryPlugin::show() it.second->show(); } } + +WayfireLockerBatteryPlugin::WayfireLockerBatteryPlugin(): + WayfireLockerPlugin("locker/battery_enable", "locker/battery_position") +{ } \ No newline at end of file diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index 25b19142..0a5d7e1c 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -1,14 +1,12 @@ #pragma once #include #include -#include #include #include #include #include -#include "../plugin.hpp" -#include "../../util/wf-option-wrap.hpp" +#include "plugin.hpp" #include "lockergrid.hpp" using DBusConnection = Glib::RefPtr; @@ -37,25 +35,22 @@ class WayfireLockerBatteryPlugin : public WayfireLockerPlugin bool setup_dbus(); public: - WayfireLockerBatteryPlugin() - {} - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + WayfireLockerBatteryPlugin(); + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; + void deinit() override; void hide(); void show(); bool show_state = true; - 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; + std::map> images; + std::map> subtexts; + std::map> labels; + std::map> grids; }; diff --git a/src/locker/plugin/clock.cpp b/src/locker/plugin/clock.cpp index dbc098b2..d0a5cdd1 100644 --- a/src/locker/plugin/clock.cpp +++ b/src/locker/plugin/clock.cpp @@ -5,10 +5,6 @@ #include "lockergrid.hpp" #include "clock.hpp" -bool WayfireLockerClockPlugin::should_enable() -{ - return (bool)enable; -} void WayfireLockerClockPlugin::update_labels(std::string text) { @@ -20,19 +16,20 @@ void WayfireLockerClockPlugin::update_labels(std::string text) label_contents = text; } -void WayfireLockerClockPlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerClockPlugin::add_output(int id, std::shared_ptr grid) { labels.emplace(id, std::shared_ptr(new Gtk::Label())); auto label = labels[id]; label->add_css_class("clock"); - label->set_label(label_contents); + label->set_markup(label_contents); label->set_justify(Gtk::Justification::CENTER); - grid->attach(*label, WfOption{"locker/clock_position"}); + grid->attach(*label, position); } -void WayfireLockerClockPlugin::remove_output(int id) +void WayfireLockerClockPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*labels[id]); labels.erase(id); } @@ -56,7 +53,8 @@ void WayfireLockerClockPlugin::update_time() this->update_labels(text.substr(i)); } -WayfireLockerClockPlugin::WayfireLockerClockPlugin() +WayfireLockerClockPlugin::WayfireLockerClockPlugin(): + WayfireLockerPlugin("locker/clock_enable", "locker/clock_position") {} void WayfireLockerClockPlugin::init() @@ -68,3 +66,8 @@ void WayfireLockerClockPlugin::init() return G_SOURCE_CONTINUE; }, 1); } + +void WayfireLockerClockPlugin::deinit() +{ + timeout.disconnect(); +} \ No newline at end of file diff --git a/src/locker/plugin/clock.hpp b/src/locker/plugin/clock.hpp index d87a87af..465b7139 100644 --- a/src/locker/plugin/clock.hpp +++ b/src/locker/plugin/clock.hpp @@ -2,20 +2,19 @@ #include #include -#include "../plugin.hpp" -#include "../../util/wf-option-wrap.hpp" +#include "plugin.hpp" +#include "wf-option-wrap.hpp" #include "lockergrid.hpp" class WayfireLockerClockPlugin : public WayfireLockerPlugin { public: WayfireLockerClockPlugin(); - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; + void deinit() override; - WfOption enable{"locker/clock_enable"}; WfOption format{"locker/clock_format"}; sigc::connection timeout; diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 0b2ef6c1..8b1aeeed 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -9,7 +9,6 @@ #include #include -#include "../../util/wf-option-wrap.hpp" #include "locker.hpp" #include "lockergrid.hpp" #include "fingerprint.hpp" @@ -22,10 +21,10 @@ */ WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : + WayfireLockerPlugin("locker/fingerprint_enable", "locker/fingerprint_position"), 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"}) + sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))) {} WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() @@ -63,7 +62,6 @@ void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr grid) { labels.emplace(id, std::shared_ptr(new Gtk::Label())); images.emplace(id, std::shared_ptr(new Gtk::Image())); @@ -227,21 +228,18 @@ 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, position); + grid->attach(*label, position); } -void WayfireLockerFingerprintPlugin::remove_output(int id) +void WayfireLockerFingerprintPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*labels[id]); + grid->remove(*images[id]); labels.erase(id); images.erase(id); } -bool WayfireLockerFingerprintPlugin::should_enable() -{ - return enable; -} - void WayfireLockerFingerprintPlugin::update_image(std::string image) { for (auto& it : images) diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 85b7178f..ffdba96a 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -7,7 +7,7 @@ #include #include "lockergrid.hpp" -#include "../plugin.hpp" +#include "plugin.hpp" class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin { @@ -21,14 +21,13 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin void on_device_acquired(const Glib::RefPtr & result); void claim_device(); void start_fingerprint_scanning(); - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; + void deinit() override; void hide(); void show(); - bool enable; bool is_scanning; bool show_state = false; void update_labels(std::string text); diff --git a/src/locker/plugin/instant.cpp b/src/locker/plugin/instant.cpp index 2dda575f..a9999577 100644 --- a/src/locker/plugin/instant.cpp +++ b/src/locker/plugin/instant.cpp @@ -2,34 +2,38 @@ #include #include -#include "../locker.hpp" +#include "locker.hpp" #include "lockergrid.hpp" +#include "plugin.hpp" #include "instant.hpp" -bool WayfireLockerInstantPlugin::should_enable() -{ - return (bool)enable; -} +WayfireLockerInstantPlugin::WayfireLockerInstantPlugin(): + WayfireLockerPlugin("locker/instant_unlock_enable", "locker/instant_unlock_position") +{ } -void WayfireLockerInstantPlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerInstantPlugin::add_output(int id, std::shared_ptr 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"); - grid->attach(*button, WfOption{"locker/instant_unlock_position"}); + grid->attach(*button, position); button->signal_clicked().connect([] () { - WayfireLockerApp::get().unlock(); + WayfireLockerApp::get().perform_unlock(); }, false); } -void WayfireLockerInstantPlugin::remove_output(int id) +void WayfireLockerInstantPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*buttons[id]); buttons.erase(id); } void WayfireLockerInstantPlugin::init() {} + +void WayfireLockerInstantPlugin::deinit() +{} \ No newline at end of file diff --git a/src/locker/plugin/instant.hpp b/src/locker/plugin/instant.hpp index 1ca3159c..50916a65 100644 --- a/src/locker/plugin/instant.hpp +++ b/src/locker/plugin/instant.hpp @@ -1,21 +1,17 @@ #pragma once #include -#include "../plugin.hpp" -#include "../../util/wf-option-wrap.hpp" +#include "plugin.hpp" #include "lockergrid.hpp" class WayfireLockerInstantPlugin : public WayfireLockerPlugin { public: - WayfireLockerInstantPlugin() - {} - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + WayfireLockerInstantPlugin(); + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; - - WfOption enable{"locker/instant_unlock_enable"}; + void deinit() override; std::unordered_map> buttons; }; diff --git a/src/locker/plugin/mpris.cpp b/src/locker/plugin/mpris.cpp index 9b40fb36..9b03232e 100644 --- a/src/locker/plugin/mpris.cpp +++ b/src/locker/plugin/mpris.cpp @@ -6,6 +6,7 @@ #include #include "lockergrid.hpp" +#include "plugin.hpp" #include "mpris.hpp" /* Widget of controls for one player on one screen @@ -243,8 +244,8 @@ void WayfireLockerMPRISCollective::rem_child(std::string id) } WayfireLockerMPRISPlugin::WayfireLockerMPRISPlugin() : - enable(WfOption{"locker/mpris_enable"}) -{} + WayfireLockerPlugin("locker/mpris_enable", "locker/mpris_position") +{ } void WayfireLockerMPRISPlugin::init() { @@ -295,17 +296,16 @@ void WayfireLockerMPRISPlugin::init() }); } -bool WayfireLockerMPRISPlugin::should_enable() -{ - return enable; -} +void WayfireLockerMPRISPlugin::deinit() +{} -void WayfireLockerMPRISPlugin::remove_output(int id) +void WayfireLockerMPRISPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*widgets[id]); widgets.erase(id); } -void WayfireLockerMPRISPlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerMPRISPlugin::add_output(int id, std::shared_ptr grid) { widgets.emplace(id, new WayfireLockerMPRISCollective()); @@ -315,7 +315,7 @@ void WayfireLockerMPRISPlugin::add_output(int id, WayfireLockerGrid *grid) collective->add_child(it.first, it.second); } - grid->attach(*collective, WfOption{"locker/mpris_position"}); + grid->attach(*collective, position); } std::string substitute_string(const std::string from, const std::string to, const std::string in) diff --git a/src/locker/plugin/mpris.hpp b/src/locker/plugin/mpris.hpp index ef91bc78..d51714ce 100644 --- a/src/locker/plugin/mpris.hpp +++ b/src/locker/plugin/mpris.hpp @@ -6,7 +6,7 @@ #include #include -#include "../plugin.hpp" +#include "plugin.hpp" #include "lockergrid.hpp" @@ -57,15 +57,13 @@ class WayfireLockerMPRISPlugin : public WayfireLockerPlugin Glib::RefPtr manager_proxy; std::map> clients; std::map> widgets; - bool enable; public: WayfireLockerMPRISPlugin(); - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; - + void deinit() override; void add_client(std::string client); void rem_client(std::string client); diff --git a/src/locker/plugin/password.cpp b/src/locker/plugin/password.cpp index 2fa94528..0553b73e 100644 --- a/src/locker/plugin/password.cpp +++ b/src/locker/plugin/password.cpp @@ -9,12 +9,9 @@ #include "locker.hpp" #include "lockergrid.hpp" +#include "plugin.hpp" #include "password.hpp" -bool WayfireLockerPasswordPlugin::should_enable() -{ - return (bool)enable; -} void WayfireLockerPasswordPlugin::update_labels(std::string text) { @@ -34,7 +31,7 @@ void WayfireLockerPasswordPlugin::blank_passwords() } } -void WayfireLockerPasswordPlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerPasswordPlugin::add_output(int id, std::shared_ptr grid) { labels.emplace(id, std::shared_ptr(new Gtk::Label())); entries.emplace(id, std::shared_ptr(new Gtk::Entry)); @@ -55,18 +52,21 @@ void WayfireLockerPasswordPlugin::add_output(int id, WayfireLockerGrid *grid) } }, true); /* Add to window */ - grid->attach(*entry, WfOption{"locker/password_position"}); - grid->attach(*label, WfOption{"locker/password_position"}); + grid->attach(*entry, position); + grid->attach(*label, position); } -void WayfireLockerPasswordPlugin::remove_output(int id) +void WayfireLockerPasswordPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*entries[id]); + grid->remove(*labels[id]); labels.erase(id); entries.erase(id); } -WayfireLockerPasswordPlugin::WayfireLockerPasswordPlugin() -{} +WayfireLockerPasswordPlugin::WayfireLockerPasswordPlugin(): + WayfireLockerPlugin("locker/password_enable", "locker/password_position") +{ } /* PAM password C code... */ int pam_conversation(int num_mesg, const struct pam_message **mesg, struct pam_response **resp, @@ -146,9 +146,12 @@ void WayfireLockerPasswordPlugin::submit_user_password(std::string password) retval = pam_end(local_auth_handle, retval); if (unlock) { - WayfireLockerApp::get().unlock(); + WayfireLockerApp::get().perform_unlock(); } } void WayfireLockerPasswordPlugin::init() {} + +void WayfireLockerPasswordPlugin::deinit() +{} \ No newline at end of file diff --git a/src/locker/plugin/password.hpp b/src/locker/plugin/password.hpp index 6d25165e..6c5807d9 100644 --- a/src/locker/plugin/password.hpp +++ b/src/locker/plugin/password.hpp @@ -3,8 +3,7 @@ #include #include -#include "../plugin.hpp" -#include "../../util/wf-option-wrap.hpp" +#include "plugin.hpp" #include "lockergrid.hpp" int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, @@ -14,15 +13,13 @@ class WayfireLockerPasswordPlugin : public WayfireLockerPlugin { public: WayfireLockerPasswordPlugin(); - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; + void deinit() 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); diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index 3323e161..7c178160 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -11,7 +11,7 @@ #include -#include "../../util/wf-option-wrap.hpp" +#include "plugin.hpp" #include "locker.hpp" #include "lockergrid.hpp" #include "pin.hpp" @@ -88,10 +88,9 @@ void PinPad::init() set_row_homogeneous(true); } -WayfireLockerPinPlugin::WayfireLockerPinPlugin() +WayfireLockerPinPlugin::WayfireLockerPinPlugin(): + WayfireLockerPlugin("locker/pin_enable", "locker/pin_position") { - WfOption enabled{"locker/pin_enable"}; - enable = enabled; if (!enable) { return; @@ -117,7 +116,7 @@ WayfireLockerPinPlugin::WayfireLockerPinPlugin() if (!f.is_open()) { std::cerr << "No PIN hash set" << std::endl; - enable = false; + disabled = true; return; } @@ -125,14 +124,14 @@ WayfireLockerPinPlugin::WayfireLockerPinPlugin() if (!getline(f, s)) { std::cerr << "No PIN hash set" << std::endl; - enable = false; + disabled = true; return; } if (s.length() != 128) { std::cerr << "Invalid PIN hash" << std::endl; - enable = false; + disabled = true; return; } @@ -142,23 +141,22 @@ WayfireLockerPinPlugin::WayfireLockerPinPlugin() void WayfireLockerPinPlugin::init() {} -bool WayfireLockerPinPlugin::should_enable() -{ - return enable; -} +void WayfireLockerPinPlugin::deinit() +{} -void WayfireLockerPinPlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerPinPlugin::add_output(int id, std::shared_ptr grid) { pinpads.emplace(id, new PinPad()); auto pinpad = pinpads[id]; pinpad->add_css_class("pinpad"); pinpad->init(); - grid->attach(*pinpad, WfOption{"locker/pin_position"}); + grid->attach(*pinpad, position); update_labels(); /* Update all to set this one? maybe overkill */ } -void WayfireLockerPinPlugin::remove_output(int id) +void WayfireLockerPinPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*pinpads[id]); pinpads.erase(id); } @@ -188,7 +186,7 @@ void WayfireLockerPinPlugin::submit_pin() auto hash = sha512(pin); if (hash == pinhash) { - WayfireLockerApp::get().unlock(); + WayfireLockerApp::get().perform_unlock(); } pin = ""; diff --git a/src/locker/plugin/pin.hpp b/src/locker/plugin/pin.hpp index 1f98003d..1d805922 100644 --- a/src/locker/plugin/pin.hpp +++ b/src/locker/plugin/pin.hpp @@ -26,10 +26,11 @@ class WayfireLockerPinPlugin : public WayfireLockerPlugin { public: WayfireLockerPinPlugin(); - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; + void deinit() override; + bool disabled = false; void update_labels(); void submit_pin(); @@ -37,8 +38,6 @@ class WayfireLockerPinPlugin : public WayfireLockerPlugin void add_digit(std::string digit); std::string sha512(const std::string input); - bool enable = false; - std::unordered_map> pinpads; std::string pin = ""; diff --git a/src/locker/plugin/user.cpp b/src/locker/plugin/user.cpp index e788ed2f..4e82a6a4 100644 --- a/src/locker/plugin/user.cpp +++ b/src/locker/plugin/user.cpp @@ -1,10 +1,11 @@ #include #include "lockergrid.hpp" +#include "plugin.hpp" #include "user.hpp" -WayfireLockerUserPlugin::WayfireLockerUserPlugin() : - enable(WfOption{"locker/user_enable"}) +WayfireLockerUserPlugin::WayfireLockerUserPlugin(): + WayfireLockerPlugin("locker/user_enable", "locker/user_position") {} void WayfireLockerUserPlugin::init() @@ -42,7 +43,10 @@ void WayfireLockerUserPlugin::init() std::cout << "No user image .face... no image in lockscreen" << std::endl; } -void WayfireLockerUserPlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerUserPlugin::deinit() +{} + +void WayfireLockerUserPlugin::add_output(int id, std::shared_ptr grid) { labels.emplace(id, Glib::RefPtr(new Gtk::Label())); images.emplace(id, Glib::RefPtr(new Gtk::Image())); @@ -73,17 +77,13 @@ void WayfireLockerUserPlugin::add_output(int id, WayfireLockerGrid *grid) box->append(*image); box->append(*label); - grid->attach(*box, WfOption{"locker/user_position"}); + grid->attach(*box, position); } -void WayfireLockerUserPlugin::remove_output(int id) +void WayfireLockerUserPlugin::remove_output(int id, std::shared_ptr grid) { + grid->remove(*boxes[id]); labels.erase(id); images.erase(id); boxes.erase(id); -} - -bool WayfireLockerUserPlugin::should_enable() -{ - return enable; -} +} \ No newline at end of file diff --git a/src/locker/plugin/user.hpp b/src/locker/plugin/user.hpp index 171ba9b4..a95de2ab 100644 --- a/src/locker/plugin/user.hpp +++ b/src/locker/plugin/user.hpp @@ -3,20 +3,17 @@ #include #include -#include "../plugin.hpp" -#include "../../util/wf-option-wrap.hpp" +#include "plugin.hpp" #include "lockergrid.hpp" class WayfireLockerUserPlugin : public WayfireLockerPlugin { public: WayfireLockerUserPlugin(); - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; - - bool enable; + void deinit() override; std::unordered_map> labels; std::unordered_map> images; diff --git a/src/locker/plugin/volume.cpp b/src/locker/plugin/volume.cpp index f188b19a..ecc44e9f 100644 --- a/src/locker/plugin/volume.cpp +++ b/src/locker/plugin/volume.cpp @@ -4,7 +4,7 @@ #include "lockergrid.hpp" #include "volume.hpp" -#include "../../util/wf-option-wrap.hpp" +#include "plugin.hpp" static void default_sink_changed(GvcMixerControl *gvc_control, guint id, gpointer user_data) @@ -55,9 +55,9 @@ void WayfireLockerVolumePlugin::update_button_images() } } -WayfireLockerVolumePlugin::WayfireLockerVolumePlugin() +WayfireLockerVolumePlugin::WayfireLockerVolumePlugin(): + WayfireLockerPlugin("locker/volume_enable", "locker/volume_position") { - enable = WfOption{"locker/volume_enable"}; /* Setup gvc control */ gvc_control = gvc_mixer_control_new("Wayfire Volume Control"); g_signal_connect(gvc_control, @@ -67,25 +67,22 @@ WayfireLockerVolumePlugin::WayfireLockerVolumePlugin() gvc_mixer_control_open(gvc_control); } -bool WayfireLockerVolumePlugin::should_enable() -{ - return (bool)enable; -} -void WayfireLockerVolumePlugin::add_output(int id, WayfireLockerGrid *grid) +void WayfireLockerVolumePlugin::add_output(int id, std::shared_ptr grid) { source_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); sink_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); + inner_boxes.emplace(id, std::shared_ptr(new Gtk::Box)); 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"); - auto inner_box = Gtk::Box(); - inner_box.append(*source_button); - inner_box.append(*sink_button); - grid->attach(inner_box, WfOption{"locker/volume_position"}); + auto inner_box = inner_boxes[id]; + inner_box->append(*source_button); + inner_box->append(*sink_button); + grid->attach(*inner_box, position); sink_button->signal_clicked().connect( [=] () @@ -114,8 +111,9 @@ void WayfireLockerVolumePlugin::add_output(int id, WayfireLockerGrid *grid) update_button_images(); } -void WayfireLockerVolumePlugin::remove_output(int id) +void WayfireLockerVolumePlugin::remove_output(int id, std::shared_ptr grid) { + source_buttons.erase(id); sink_buttons.erase(id); } @@ -123,6 +121,9 @@ void WayfireLockerVolumePlugin::remove_output(int id) void WayfireLockerVolumePlugin::init() {} +void WayfireLockerVolumePlugin::deinit() +{} + void WayfireLockerVolumePlugin::disconnect_gvc_stream_sink_signals() { if (notify_sink_muted_signal) diff --git a/src/locker/plugin/volume.hpp b/src/locker/plugin/volume.hpp index 178c574c..44c62ee7 100644 --- a/src/locker/plugin/volume.hpp +++ b/src/locker/plugin/volume.hpp @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include #include @@ -23,17 +22,17 @@ class WayfireLockerVolumePlugin : public WayfireLockerPlugin public: WayfireLockerVolumePlugin(); - void add_output(int id, WayfireLockerGrid *grid) override; - void remove_output(int id) override; - bool should_enable() override; + void add_output(int id, std::shared_ptr grid) override; + void remove_output(int id, std::shared_ptr grid) override; void init() override; - bool enable; + void deinit() override; 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; + std::map> inner_boxes; + std::map> sink_buttons; + std::map> source_buttons; }; diff --git a/src/panel/panel.cpp b/src/panel/panel.cpp index 34bdc513..7b1fb93a 100644 --- a/src/panel/panel.cpp +++ b/src/panel/panel.cpp @@ -14,7 +14,6 @@ #include #include "panel.hpp" -#include "wf-ipc.hpp" #include "widgets/battery.hpp" #include "widgets/command-output.hpp" #include "widgets/language.hpp" @@ -416,9 +415,20 @@ void WayfirePanelApp::create(int argc, char **argv) } instance = std::unique_ptr(new WayfirePanelApp{}); + instance->init_app(); instance->run(argc, argv); } +std::string WayfirePanelApp::get_application_name() +{ + return "org.wayfire.panel"; +} + +Gio::Application::Flags WayfirePanelApp::get_extra_application_flags() +{ + return Gio::Application::Flags::NON_UNIQUE; +} + WayfirePanelApp::~WayfirePanelApp() = default; WayfirePanelApp::WayfirePanelApp() : WayfireShellApp(), priv(new impl()) {} diff --git a/src/panel/panel.hpp b/src/panel/panel.hpp index cae9903e..e9462e45 100644 --- a/src/panel/panel.hpp +++ b/src/panel/panel.hpp @@ -6,6 +6,7 @@ #include #include +#include "giomm/application.h" #include "wf-shell-app.hpp" class WayfirePanel @@ -27,6 +28,8 @@ class WayfirePanelApp : public WayfireShellApp public: WayfirePanel *panel_for_wl_output(wl_output *output); static WayfirePanelApp& get(); + std::string get_application_name() override; + Gio::Application::Flags get_extra_application_flags() override; /* Starts the program. get() is valid afterward the first (and the only) * call to create() */ diff --git a/src/util/wf-shell-app.cpp b/src/util/wf-shell-app.cpp index 7883ecbe..dc72fa07 100644 --- a/src/util/wf-shell-app.cpp +++ b/src/util/wf-shell-app.cpp @@ -187,6 +187,11 @@ static struct wl_registry_listener registry_listener = void WayfireShellApp::on_activate() { + if(activated) + { + return; + } + activated = true; app->hold(); // load wf-shell if available @@ -282,12 +287,22 @@ void WayfireShellApp::rem_output(GMonitor monitor) handle_output_removed(it->get()); monitors.erase(it); } + +} + +Gio::Application::Flags WayfireShellApp::get_extra_application_flags() +{ + return Gio::Application::Flags::NONE; } WayfireShellApp::WayfireShellApp() +{ +} + +void WayfireShellApp::init_app() { std::cout << "setting up" << std::endl; - app = Gtk::Application::create("", Gio::Application::Flags::HANDLES_COMMAND_LINE); + app = Gtk::Application::create(this->get_application_name(), Gio::Application::Flags::HANDLES_COMMAND_LINE | this->get_extra_application_flags()); app->signal_activate().connect( sigc::mem_fun(*this, &WayfireShellApp::on_activate)); app->add_main_option_entry( diff --git a/src/util/wf-shell-app.hpp b/src/util/wf-shell-app.hpp index fc43f890..7ce6cd13 100644 --- a/src/util/wf-shell-app.hpp +++ b/src/util/wf-shell-app.hpp @@ -49,6 +49,7 @@ class WayfireShellApp std::optional cmdline_css; Glib::RefPtr app; + bool activated = false; void output_list_updated(int pos, int rem, int add); virtual void add_output(GMonitor monitor); @@ -74,6 +75,7 @@ class WayfireShellApp WayfireShellApp(); virtual ~WayfireShellApp(); + void init_app(); virtual std::string get_config_file(); virtual std::string get_css_config_dir(); @@ -84,7 +86,8 @@ class WayfireShellApp void on_css_reload(); void clear_css_rules(); void add_css_file(std::string file, int priority); - + virtual Gio::Application::Flags get_extra_application_flags(); + virtual std::string get_application_name() = 0; /** * WayfireShellApp is a singleton class. From b6517f821dbb72cf658b96696da3b9f1728eea39 Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 25 Jan 2026 13:33:56 +0000 Subject: [PATCH 37/67] - Reveal/Hide Ui elements on user interaction & timeout - DeInit plugins when lock ends - ReInit plugins when new lock is required - Hotload some config - Removed init from constructors --- metadata/locker.xml | 5 ++ src/locker/locker.cpp | 74 ++++++++++++++++--------- src/locker/locker.hpp | 8 +-- src/locker/lockscreen.hpp | 89 +++++++++++++++++++++++++++++++ src/locker/plugin/battery.cpp | 22 +++++--- src/locker/plugin/battery.hpp | 1 + src/locker/plugin/fingerprint.cpp | 78 +++++++++++++++++++++++---- src/locker/plugin/fingerprint.hpp | 14 +++-- src/locker/plugin/mpris.cpp | 10 +++- src/locker/plugin/mpris.hpp | 3 +- src/locker/plugin/pin.cpp | 8 +++ src/locker/plugin/user.cpp | 5 +- src/locker/plugin/user.hpp | 7 ++- src/locker/plugin/volume.cpp | 33 ++++++++---- src/locker/plugin/volume.hpp | 4 +- 15 files changed, 292 insertions(+), 69 deletions(-) create mode 100644 src/locker/lockscreen.hpp diff --git a/metadata/locker.xml b/metadata/locker.xml index 915bec62..75f03a21 100644 --- a/metadata/locker.xml +++ b/metadata/locker.xml @@ -13,6 +13,11 @@ <_short>Exit lockscreen process on unlock true + <_short>Password diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index ae9d425f..994b32df 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -14,6 +13,7 @@ #include "css-config.hpp" #include "giomm/application.h" #include "lockergrid.hpp" +#include "lockscreen.hpp" #include "plugin/battery.hpp" #include "plugin/clock.hpp" #include "plugin/instant.hpp" @@ -45,6 +45,7 @@ WayfireLockerApp::~WayfireLockerApp() void WayfireLockerApp::perform_lock() { + if (is_debug()) { if(!m_is_locked) @@ -110,32 +111,25 @@ void WayfireLockerApp::on_activate() plugins.emplace("mpris", Plugin(new WayfireLockerMPRISPlugin())); plugins.emplace("aboutuser", Plugin(new WayfireLockerUserPlugin())); - for (auto& it : plugins) + /* Create plugin option callbacks */ + for (auto &it : plugins) { Plugin plugin = it.second; - if (plugin->enable) - { - it.second->init(); - } plugin->enable.set_callback( [plugin, this] () { if (plugin->enable) { - std::cout << "Plugin enable" << std::endl; plugin->init(); for(auto &it : window_list) { - std::cout << "Adding to window"<add_output(id, grid_list[id]); + plugin->add_output(id, it.second->grid); } } else { - std::cout << "Plugin disable" << std::endl; for(auto &it : window_list) { - std::cout << "Removing from window"<remove_output(id, grid_list[id]); + plugin->remove_output(id, it.second->grid); } plugin->deinit(); } @@ -143,12 +137,12 @@ void WayfireLockerApp::on_activate() ); plugin->position.set_callback( [this, plugin] () { - for(auto &it : grid_list) + for(auto &it : window_list) { int id = it.first; - auto grid = it.second; - plugin->remove_output(id, grid); - plugin->add_output(id, grid); + auto window = it.second; + plugin->remove_output(id, window->grid); + plugin->add_output(id, window->grid); } } ); @@ -156,27 +150,47 @@ void WayfireLockerApp::on_activate() perform_lock(); } +/** Called just as lock starts but before window is shown */ +void WayfireLockerApp::init_plugins() +{ + for (auto &it : plugins) + { + Plugin plugin = it.second; + if (plugin->enable) + { + it.second->init(); + } + } +} + +/** Called after an unlock */ +void WayfireLockerApp::deinit_plugins() +{ + for (auto &it : plugins) + { + Plugin plugin = it.second; + if (plugin->enable) + { + it.second->deinit(); + } + } +} + /* 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 = std::shared_ptr(new WayfireLockerGrid()); - - window->set_child(*grid); - grid->set_expand(true); - grid_list.emplace(id, grid); - window_list.emplace(id, window); + window_list.emplace(id, new WayfireLockerAppLockscreen()); + auto window = window_list[id]; for (auto& it : plugins) { Plugin plugin = it.second; if (plugin->enable) { - it.second->add_output(id, grid); + it.second->add_output(id, window->grid); } } @@ -187,11 +201,12 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) Plugin plugin = it.second; if (plugin->enable) { - plugin->remove_output(id, grid_list[id]); + plugin->remove_output(id, window_list[id]->grid); } } if (m_is_debug) { + deinit_plugins(); m_is_locked = false; if (exit_on_unlock) { @@ -203,6 +218,7 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) }, false); if (is_debug()) { + init_plugins(); m_is_locked = true; window->present(); } else @@ -246,6 +262,10 @@ void WayfireLockerApp::create(int argc, char **argv) bool WayfireLockerApp::is_locked() { + if (!m_is_debug) + { + return gtk_session_lock_instance_is_locked(lock); + } return m_is_locked; } @@ -272,6 +292,7 @@ int main(int argc, char **argv) void on_session_locked_c(GtkSessionLockInstance *lock, void *data) { WayfireLockerApp::get().set_is_locked(true); + WayfireLockerApp::get().init_plugins(); std::cout << "Session locked" << std::endl; } @@ -288,6 +309,7 @@ void on_session_lock_failed_c(GtkSessionLockInstance *lock, void *data) void on_session_unlocked_c(GtkSessionLockInstance *lock, void *data) { WayfireLockerApp::get().set_is_locked(false); + WayfireLockerApp::get().deinit_plugins(); std::cout << "Session unlocked" << std::endl; if (WayfireLockerApp::get().exit_on_unlock) { diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index c207e18c..526f1877 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -1,10 +1,10 @@ #pragma once #include -#include #include #include #include +#include "lockscreen.hpp" #include "wf-shell-app.hpp" #include "plugin.hpp" @@ -29,8 +29,7 @@ class WayfireLockerApp : public WayfireShellApp bool m_is_locked = false; int window_id_count = 0; - std::map> window_list; - std::map> grid_list; + std::map> window_list; std::vector> css_rules; @@ -67,6 +66,7 @@ class WayfireLockerApp : public WayfireShellApp /* Give commands to compositor about lock state, or emulate them*/ void perform_unlock(); void perform_lock(); - + void init_plugins(); + void deinit_plugins(); private: }; diff --git a/src/locker/lockscreen.hpp b/src/locker/lockscreen.hpp new file mode 100644 index 00000000..c419c75f --- /dev/null +++ b/src/locker/lockscreen.hpp @@ -0,0 +1,89 @@ +#pragma once +#include +#include +#include +#include + +#include "gtkmm/eventcontroller.h" +#include "gtkmm/gesture.h" +#include "wf-option-wrap.hpp" +#include "lockergrid.hpp" +class WayfireLockerAppLockscreen: public Gtk::Window +{ + public: + std::shared_ptr grid; + Gtk::Revealer revealer; + sigc::connection timeout; + WfOption hide_timeout {"locker/hide_time"}; + + WayfireLockerAppLockscreen() + { + grid = std::shared_ptr(new WayfireLockerGrid()); + set_child(revealer); + add_css_class("wf-locker"); + revealer.set_transition_type(Gtk::RevealerTransitionType::CROSSFADE); + revealer.set_child(*grid); + grid->set_expand(true); + revealer.set_reveal_child(false); + + /* Mouse press or screen touch */ + auto click_gesture = Gtk::GestureClick::create(); + click_gesture->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); + click_gesture->signal_released().connect([=] (int count, double x, double y) + { + start_disappear_timer(); + /* If we are hidden and have not started showing... */ + if(!revealer.get_reveal_child()) + { + revealer.set_reveal_child(true); + click_gesture->set_state(Gtk::EventSequenceState::CLAIMED); + } + }); + add_controller(click_gesture); + + /* Mouse movement */ + auto pointer_gesture = Gtk::EventControllerMotion::create(); + pointer_gesture->signal_motion().connect([=] (double x, double y) + { + start_disappear_timer(); + /* If we are hidden and have not started showing... */ + if(!revealer.get_reveal_child()) + { + revealer.set_reveal_child(true); + } + }); + add_controller(pointer_gesture); + /* Keypress */ + auto typing_gesture = Gtk::EventControllerKey::create(); + typing_gesture->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); + typing_gesture->signal_key_pressed().connect([=] (guint keyval, guint keycode, + Gdk::ModifierType state) + { + start_disappear_timer(); + if(!revealer.get_reveal_child()) + { + revealer.set_reveal_child(true); + return true; + } + return false; + }, false); + add_controller(typing_gesture); + } + + void start_disappear_timer() + { + if (timeout) + { + timeout.disconnect(); + } + if (hide_timeout>0) + { + timeout = Glib::signal_timeout().connect_seconds( + [this] () + { + revealer.set_reveal_child(false); + return G_SOURCE_REMOVE; + }, 5); + } + } +}; \ No newline at end of file diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index 3dbe9e45..a5013412 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -128,17 +128,20 @@ void WayfireLockerBatteryPlugin::remove_output(int id, std::shared_ptrget_cached_property(present, SHOULD_DISPLAY); if (present.get()) { - display_device->signal_properties_changed().connect( + signal = display_device->signal_properties_changed().connect( sigc::mem_fun(*this, &WayfireLockerBatteryPlugin::on_properties_changed)); return true; @@ -217,6 +220,11 @@ void WayfireLockerBatteryPlugin::on_properties_changed( void WayfireLockerBatteryPlugin::update_details() { + if (display_device==nullptr) + { + std::cout << "No battery proxy!" < type; display_device->get_cached_property(type, TYPE); diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index 0a5d7e1c..388fff0c 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -33,6 +33,7 @@ class WayfireLockerBatteryPlugin : public WayfireLockerPlugin const Gio::DBus::Proxy::MapChangedProperties& properties, const std::vector& invalidated); bool setup_dbus(); + sigc::connection signal; public: WayfireLockerBatteryPlugin(); diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 8b1aeeed..7a91176b 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -21,10 +21,7 @@ */ WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : - WayfireLockerPlugin("locker/fingerprint_enable", "locker/fingerprint_position"), - dbus_name_id(Gio::DBus::own_name(Gio::DBus::BusType::SYSTEM, - "net.reactivated.Fprint", - sigc::mem_fun(*this, &WayfireLockerFingerprintPlugin::on_bus_acquired))) + WayfireLockerPlugin("locker/fingerprint_enable", "locker/fingerprint_position") {} WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() @@ -35,7 +32,7 @@ WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() } } -void WayfireLockerFingerprintPlugin::on_bus_acquired(const Glib::RefPtr & connection, +void WayfireLockerFingerprintPlugin::on_connection(const Glib::RefPtr & connection, const Glib::ustring & name) { /* Bail here if config has this disabled */ @@ -99,10 +96,15 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrsignal_signal().connect([this] (const Glib::ustring & sender_name, + signal = device_proxy->signal_signal().connect([this] (const Glib::ustring & sender_name, const Glib::ustring & signal_name, const Glib::VariantContainerBase & params) { + std::cout << signal_name << " " << device_proxy << std::endl; + if (device_proxy==nullptr) + { + return; // Skip close-down messages + } if (signal_name == "VerifyStatus") { Glib::Variant mesg; @@ -146,6 +148,11 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_sync("VerifyStop"); } + } else if (signal_name == "VerifyFingerSelected") + { + Glib::Variant finger_name; + params.get_child(finger_name,0); + std::cout << "Finger : " << finger_name.get() << std::endl; } }, false); claim_device(); @@ -178,7 +185,12 @@ 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 */ + * is a button which locks the screen */ +} + +void WayfireLockerFingerprintPlugin::release_device() +{ + device_proxy->call_sync("Release"); } void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() @@ -202,11 +214,59 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() } } +void WayfireLockerFingerprintPlugin::stop_fingerprint_scanning() +{ + device_proxy->call_sync("VerifyStop"); + is_scanning = false; +} + void WayfireLockerFingerprintPlugin::init() -{} +{ + 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; + } + Gio::DBus::Proxy::create( + connection, + "net.reactivated.Fprint", + "/net/reactivated/Fprint/Manager", + "net.reactivated.Fprint.Manager", + [this] (const Glib::RefPtr & result) + { + auto manager_proxy = Gio::DBus::Proxy::create_finish(result); + 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? */ + { + hide(); + return; + } + }); +} void WayfireLockerFingerprintPlugin::deinit() -{} +{ + if(is_scanning) + { + stop_fingerprint_scanning(); + } + release_device(); + if(signal) + { + signal.disconnect(); + } + device_proxy = nullptr; +} void WayfireLockerFingerprintPlugin::add_output(int id, std::shared_ptr grid) { diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index ffdba96a..2906a331 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -5,22 +5,27 @@ #include #include #include +#include #include "lockergrid.hpp" #include "plugin.hpp" - +using DBusConnection = Glib::RefPtr; +using DBusProxy = Glib::RefPtr; class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin { - public: - guint dbus_name_id; + private: + DBusConnection connection; Glib::RefPtr device_proxy; + public: WayfireLockerFingerprintPlugin(); ~WayfireLockerFingerprintPlugin(); - void on_bus_acquired(const Glib::RefPtr & connection, const Glib::ustring & name); + void on_connection(const Glib::RefPtr & connection, const Glib::ustring & name); void on_device_acquired(const Glib::RefPtr & result); void claim_device(); + void release_device(); void start_fingerprint_scanning(); + void stop_fingerprint_scanning(); void add_output(int id, std::shared_ptr grid) override; void remove_output(int id, std::shared_ptr grid) override; void init() override; @@ -28,6 +33,7 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin void hide(); void show(); + sigc::connection signal; bool is_scanning; bool show_state = false; void update_labels(std::string text); diff --git a/src/locker/plugin/mpris.cpp b/src/locker/plugin/mpris.cpp index 9b03232e..49731204 100644 --- a/src/locker/plugin/mpris.cpp +++ b/src/locker/plugin/mpris.cpp @@ -270,7 +270,7 @@ void WayfireLockerMPRISPlugin::init() } /* https://dbus.freedesktop.org/doc/dbus-java/api/org/freedesktop/DBus.NameOwnerChanged.html */ - manager_proxy->signal_signal().connect( + signal = manager_proxy->signal_signal().connect( [this] (const Glib::ustring & sender_name, const Glib::ustring & signal_name, const Glib::VariantContainerBase & params) @@ -297,7 +297,13 @@ void WayfireLockerMPRISPlugin::init() } void WayfireLockerMPRISPlugin::deinit() -{} +{ + if (signal) + { + signal.disconnect(); + } + manager_proxy = nullptr; +} void WayfireLockerMPRISPlugin::remove_output(int id, std::shared_ptr grid) { diff --git a/src/locker/plugin/mpris.hpp b/src/locker/plugin/mpris.hpp index d51714ce..8733df70 100644 --- a/src/locker/plugin/mpris.hpp +++ b/src/locker/plugin/mpris.hpp @@ -8,6 +8,7 @@ #include "plugin.hpp" #include "lockergrid.hpp" +#include "sigc++/connection.h" std::string substitute_string(const std::string from, const std::string to, const std::string in); @@ -57,7 +58,7 @@ class WayfireLockerMPRISPlugin : public WayfireLockerPlugin Glib::RefPtr manager_proxy; std::map> clients; std::map> widgets; - + sigc::connection signal; public: WayfireLockerMPRISPlugin(); void add_output(int id, std::shared_ptr grid) override; diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index 7c178160..22f17e4a 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -146,6 +146,10 @@ void WayfireLockerPinPlugin::deinit() void WayfireLockerPinPlugin::add_output(int id, std::shared_ptr grid) { + if(disabled) + { + return; + } pinpads.emplace(id, new PinPad()); auto pinpad = pinpads[id]; pinpad->add_css_class("pinpad"); @@ -156,6 +160,10 @@ void WayfireLockerPinPlugin::add_output(int id, std::shared_ptr grid) { + if(disabled) + { + return; + } grid->remove(*pinpads[id]); pinpads.erase(id); } diff --git a/src/locker/plugin/user.cpp b/src/locker/plugin/user.cpp index 4e82a6a4..27fd489c 100644 --- a/src/locker/plugin/user.cpp +++ b/src/locker/plugin/user.cpp @@ -34,7 +34,6 @@ void WayfireLockerUserPlugin::init() struct stat sb; if ((stat(home_path_file.c_str(), &sb) == 0) && !(sb.st_mode & S_IFDIR)) { - std::cout << home_path_file << " Selected" << std::endl; image_path = home_path_file; return; } @@ -44,7 +43,9 @@ void WayfireLockerUserPlugin::init() } void WayfireLockerUserPlugin::deinit() -{} +{ + image_path=""; +} void WayfireLockerUserPlugin::add_output(int id, std::shared_ptr grid) { diff --git a/src/locker/plugin/user.hpp b/src/locker/plugin/user.hpp index a95de2ab..74b9834d 100644 --- a/src/locker/plugin/user.hpp +++ b/src/locker/plugin/user.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include #include "plugin.hpp" #include "lockergrid.hpp" @@ -15,9 +14,9 @@ class WayfireLockerUserPlugin : public WayfireLockerPlugin void init() override; void deinit() override; - std::unordered_map> labels; - std::unordered_map> images; - std::unordered_map> boxes; + std::map> labels; + std::map> images; + std::map> boxes; std::string image_path = ""; }; diff --git a/src/locker/plugin/volume.cpp b/src/locker/plugin/volume.cpp index ecc44e9f..6bcd4fc0 100644 --- a/src/locker/plugin/volume.cpp +++ b/src/locker/plugin/volume.cpp @@ -58,13 +58,7 @@ void WayfireLockerVolumePlugin::update_button_images() WayfireLockerVolumePlugin::WayfireLockerVolumePlugin(): WayfireLockerPlugin("locker/volume_enable", "locker/volume_position") { - /* 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); + } @@ -119,10 +113,31 @@ void WayfireLockerVolumePlugin::remove_output(int id, std::shared_ptr #include "gvc-mixer-control.h" -#include "../plugin.hpp" +#include "plugin.hpp" #include "lockergrid.hpp" class WayfireLockerVolumePlugin : public WayfireLockerPlugin @@ -17,6 +17,8 @@ class WayfireLockerVolumePlugin : public WayfireLockerPlugin GvcMixerStream *gvc_source_stream = NULL; gulong notify_sink_muted_signal = 0; gulong notify_source_muted_signal = 0; + gulong notify_sink_changed = 0; + gulong notify_source_changed = 0; void disconnect_gvc_stream_sink_signals(); void disconnect_gvc_stream_source_signals(); From 4e027ee7d1e157a6f6386b5d0f079db5057426dd Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 25 Jan 2026 13:47:59 +0000 Subject: [PATCH 38/67] - sanity check --- src/locker/plugin/fingerprint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 7a91176b..2882bfb5 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -143,7 +143,7 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_sync("VerifyStop"); From 6ec57d7a16f74cedcfba2e2c01a892a4744455ce Mon Sep 17 00:00:00 2001 From: trigg Date: Sun, 25 Jan 2026 14:11:39 +0000 Subject: [PATCH 39/67] - explicitly override --- src/locker/locker.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index 526f1877..648571d1 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -41,7 +41,7 @@ class WayfireLockerApp : public WayfireShellApp { return (WayfireLockerApp&)WayfireShellApp::get(); } - Gio::Application::Flags get_extra_application_flags(); + Gio::Application::Flags get_extra_application_flags() override; std::string get_application_name() override; /* Starts the program. get() is valid afterward the first (and the only) From a3d282d616a071459f8201da69486b3c6df481b8 Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Sun, 25 Jan 2026 22:16:34 -0700 Subject: [PATCH 40/67] Add weather plugin Depends on weather-fetch.py running periodically. The script is included as wf-shell/data/weather-fetch.py. Usage instructions are at the top of the script. --- data/weather-fetch.py | 174 ++++++++++++++++++++++++++++++++++ meson.build | 1 + metadata/locker.xml | 50 ++++++++++ src/locker/locker.cpp | 3 + src/locker/meson.build | 4 +- src/locker/plugin/weather.cpp | 114 ++++++++++++++++++++++ src/locker/plugin/weather.hpp | 27 ++++++ 7 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 data/weather-fetch.py create mode 100644 src/locker/plugin/weather.cpp create mode 100644 src/locker/plugin/weather.hpp diff --git a/data/weather-fetch.py b/data/weather-fetch.py new file mode 100644 index 00000000..542d8d63 --- /dev/null +++ b/data/weather-fetch.py @@ -0,0 +1,174 @@ +# +# The MIT License (MIT) +# +# Copyright (c) 2026 Scott Moreau +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# + +# +# OpenWeatherMap Free API Key Signup +# +# 1) Navigate to https://home.openweathermap.org/users/sign_up +# +# 2) Fill out the form +# +# 3) Complete the captcha +# +# 4) Click Create Account button +# +# 5) Check email and verify account +# +# 6) Wait about 2 hours for the key to become active +# +# 7) Navigate to https://home.openweathermap.org/api_keys +# +# 8) Copy the Default API key for use +# +# 9) Run this script with your API key and location +# +# +# Examples: +# +# $ python weather.py --help +# +# usage: Weather [-h] [-l LOCATION] [-k APIKEY] [-m] +# +# Get weather data with icon. +# +# options: +# -h, --help show this help message and exit +# -l, --location LOCATION +# -k, --apikey APIKEY +# -m, --metric +# +# Copyright (c) 2026 Scott Moreau +# +# $ python weather.py -k 8b0017275348eaf1a674045c86dadd32 -l 80918 +# +# Weather information for Pikeview, US: 15°F - light snow +# +# $ python weather.py -k 8b0017275348eaf1a674045c86dadd32 -l London -m +# +# Weather information for London, GB: 5°C - overcast clouds +# +# Writes ~/.local/share/weather/data/data.json in the following format: +# +# { +# "temp": "5\u00b0C", +# "conditions": "Clouds", +# "icon": "/home/user/.local/share/weather/icons/04n@2x.png" +# } +# +# Applications can then read this file to get the current weather and icon +# +# This script is intended to be run periodically in the background: +# +# while true; do python weather.py [options]; sleep 10m; done +# + + +from datetime import datetime +from pathlib import Path +import requests +import argparse +import json +import sys +import os + +weather = {} + +def get_weather_info(): + if weather["api_key"] is None: + print("Set OpenWeatherMap api key to enable weather updates.") + return + if weather["location_key"] is None: + print("Set OpenWeatherMap location to get localized weather updates.") + return + + current_time = datetime.now().time() + formatted_time = current_time.strftime("%l:%M:%S") + print(formatted_time, "- Retrieving weather information..") + + try: + if weather["metric_units"] is True: + units = "metric" + else: + units = "imperial" + weather_data_url = "http://api.openweathermap.org/data/2.5/weather?q=" + str(weather["location_key"]) + "&units=" + units + "&appid=" + str(weather["api_key"]) + weather_data = json.loads(requests.get(weather_data_url).content) + #print(weather_data) + if weather["metric_units"] is True: + weather["temperature"] = str(int(weather_data["main"]["temp"])) + "°C" + else: + weather["temperature"] = str(int(weather_data["main"]["temp"])) + "°F" + weather_icon_code = weather_data["weather"][0]["icon"] + weather_icon_name = weather_icon_code + "@2x.png" + weather_icon_path = weather["icon_directory"] + "/" + weather_icon_name + if not os.path.exists(weather_icon_path): + weather_icon_url = "https://openweathermap.org/img/wn/" + weather_icon_name + img_data = requests.get(weather_icon_url).content + with open(weather_icon_path, 'wb') as weather_icon: + weather_icon.write(img_data) + print(f"Weather information for {weather_data["name"]}, {weather_data["sys"]["country"]}: {weather["temperature"]} - {weather_data["weather"][0]["description"]}") + data = { + "temp": weather["temperature"], + "conditions": weather_data["weather"][0]["main"], + "icon": weather_icon_path + } + with open(weather["data_directory"] + "/" + "data.json", "w") as file: + json.dump(data, file, indent=4) + + except Exception as e: + print("Failed to update weather:", e) + exit(-1) + +def main(): + parser = argparse.ArgumentParser( + prog="Weather", + description="Get weather data with icon.", + epilog="Copyright (c) 2026 Scott Moreau ") + parser.add_argument("-l", "--location") + parser.add_argument("-k", "--apikey") + parser.add_argument("-m", "--metric", action="store_true") + args = parser.parse_args() + if args.apikey is None: + print("Provide OpenWeatherMap APIKEY with -k or --apikey") + exit(-1) + if args.location is None: + print("Provide OpenWeatherMap location with -l or --location") + exit(-1) + weather["location_key"] = args.location + weather["api_key"] = args.apikey + weather["metric_units"] = args.metric + + weather["icon_directory"] = os.getenv("HOME") + "/.local/share/weather/icons" + icon_dir = Path(weather["icon_directory"]) + if not icon_dir.exists(): + icon_dir.mkdir(parents=True, exist_ok=True) + + weather["data_directory"] = os.getenv("HOME") + "/.local/share/weather/data" + data_dir = Path(weather["data_directory"]) + if not data_dir.exists(): + data_dir.mkdir(parents=True, exist_ok=True) + + get_weather_info() + +if __name__ == "__main__": + main() diff --git a/meson.build b/meson.build index e472534f..bf8bf512 100644 --- a/meson.build +++ b/meson.build @@ -28,6 +28,7 @@ libgvc = subproject('gvc', default_options: ['static=true'], required: get_optio xkbregistry = dependency('xkbregistry') json = subproject('wf-json').get_variable('wfjson') openssl = dependency('openssl') +yyjson = dependency('yyjson') if get_option('wayland-logout') == true wayland_logout = subproject('wayland-logout') diff --git a/metadata/locker.xml b/metadata/locker.xml index 75f03a21..3580affd 100644 --- a/metadata/locker.xml +++ b/metadata/locker.xml @@ -231,6 +231,56 @@ + <_short>Weather + + + + + <_short>User + <_short>Password diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 87d837cd..f4547a89 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -8,10 +9,10 @@ #include #include #include +#include #include #include "css-config.hpp" -#include "giomm/application.h" #include "lockergrid.hpp" #include "lockscreen.hpp" #include "plugin/battery.hpp" @@ -60,18 +61,45 @@ void WayfireLockerApp::perform_lock() } } +/* Called before each activate */ +void WayfireLockerApp::command_line() +{ + //virtual bool parse_cfgfile(const Glib::ustring & option_name, + /// const Glib::ustring & value, bool has_value) + can_early_wake = true; + app->add_main_option_entry( + [=](const Glib::ustring & option_name, + const Glib::ustring & value, bool has_value){ + can_early_wake = false; + return true; + }, + "now", 'n', "Instant lock", "", Glib::OptionEntry::Flags::NO_ARG); +} + void WayfireLockerApp::on_activate() { if (activated) { if (!m_is_locked) { + if (can_early_wake) + { + Glib::signal_timeout().connect_seconds([this](){ + can_early_wake = false; + return G_SOURCE_REMOVE; + }, WfOption {"locker/prewake"}); + } perform_lock(); } return; } - std::cout << "Starting App" << std::endl; + /* Set a timer for early-wake unlock */ WayfireShellApp::on_activate(); + Glib::signal_timeout().connect_seconds([this](){ + can_early_wake = false; + return G_SOURCE_REMOVE; + }, WfOption {"locker/prewake"}); + /* TODO Hot config for this? */ exit_on_unlock = WfOption{"locker/exit_on_unlock"}; auto debug = Glib::getenv("WF_LOCKER_DEBUG"); @@ -80,7 +108,6 @@ void WayfireLockerApp::on_activate() 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); @@ -101,6 +128,7 @@ void WayfireLockerApp::on_activate() 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/prewake", ".fade-in {animation-name: slowfade;animation-duration: ", "s; animation-timing-function: linear; animation-iteration-count: 1; animation-fill-mode: forwards;} @keyframes slowfade { from {opacity:0;} to {opacity:1;}}"); /* Init plugins */ plugins.emplace("clock", Plugin(new WayfireLockerClockPlugin())); @@ -231,24 +259,33 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) } /* Called on any successful auth to unlock & end locker */ -void WayfireLockerApp::perform_unlock() +void WayfireLockerApp::perform_unlock(std::string reason) { - if (m_is_debug) - { - /* We need to manually close in debug mode */ - for(auto &it : window_list) + /* Offset the actual logic so that any callbacks that call + this get a chance to exit cleanly. */ + Glib::signal_idle().connect([this, reason] () { + std::cout << "Unlocked : " << reason << std::endl; + if (m_is_debug) { - it.second->close(); + /* We need to manually close in debug mode */ + for(auto &it : window_list) + { + it.second->close(); + } + if (WayfireLockerApp::get().exit_on_unlock) + { + exit(0); + } + } else + { + gtk_session_lock_instance_unlock(lock); } - if (WayfireLockerApp::get().exit_on_unlock) + for(auto &it : window_list) { - exit(0); + it.second->disconnect(); } - } else - { - gtk_session_lock_instance_unlock(lock); - } - window_list.clear(); + return G_SOURCE_REMOVE; + }); } void WayfireLockerApp::create(int argc, char **argv) @@ -287,22 +324,21 @@ int main(int argc, char **argv) } WayfireLockerApp::create(argc, argv); - std::cout << "Exit" << std::endl; return 0; } /* lock session calllbacks */ void on_session_locked_c(GtkSessionLockInstance *lock, void *data) { + std::cout << "Session locked" << std::endl; WayfireLockerApp::get().set_is_locked(true); WayfireLockerApp::get().init_plugins(); - std::cout << "Session locked" << std::endl; } void on_session_lock_failed_c(GtkSessionLockInstance *lock, void *data) { - WayfireLockerApp::get().set_is_locked(false); std::cout << "Session lock failed" << std::endl; + WayfireLockerApp::get().set_is_locked(false); if (WayfireLockerApp::get().exit_on_unlock) { exit(0); @@ -311,9 +347,9 @@ void on_session_lock_failed_c(GtkSessionLockInstance *lock, void *data) void on_session_unlocked_c(GtkSessionLockInstance *lock, void *data) { + std::cout << "Session unlocked" << std::endl; WayfireLockerApp::get().set_is_locked(false); WayfireLockerApp::get().deinit_plugins(); - std::cout << "Session unlocked" << std::endl; if (WayfireLockerApp::get().exit_on_unlock) { // Exiting too early causes a lock-out @@ -322,6 +358,10 @@ void on_session_unlocked_c(GtkSessionLockInstance *lock, void *data) exit(0); },1); } + // Lose windows + WayfireLockerApp::get().window_list.clear(); + // Replace the lock object + //lock = gtk_session_lock_instance_new(); } void on_monitor_present_c(GtkSessionLockInstance *lock, GdkMonitor *monitor, void *data) @@ -360,3 +400,12 @@ Plugin WayfireLockerApp::get_plugin(std::string name) return plugins.at(name); } + +void WayfireLockerApp::user_activity() +{ + if (can_early_wake) + { + can_early_wake = false; + perform_unlock("Early Activity"); + } +} \ No newline at end of file diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index 648571d1..d9498734 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -14,6 +14,7 @@ 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: @@ -27,13 +28,10 @@ class WayfireLockerApp : public WayfireShellApp bool m_is_debug = false; bool m_is_locked = false; + bool instant_lock = false; int window_id_count = 0; - std::map> window_list; - std::vector> css_rules; - - public: using WayfireShellApp::WayfireShellApp; static void create(int argc, char **argv); @@ -43,6 +41,7 @@ class WayfireLockerApp : public WayfireShellApp } Gio::Application::Flags get_extra_application_flags() override; std::string get_application_name() override; + void command_line() override; /* Starts the program. get() is valid afterward the first (and the only) * call to create() */ @@ -64,9 +63,12 @@ class WayfireLockerApp : public WayfireShellApp Plugin get_plugin(std::string name); /* Give commands to compositor about lock state, or emulate them*/ - void perform_unlock(); + void perform_unlock(std::string reason); void perform_lock(); void init_plugins(); void deinit_plugins(); - private: + bool can_early_wake; + void user_activity(); + + std::map> window_list; }; diff --git a/src/locker/lockscreen.cpp b/src/locker/lockscreen.cpp new file mode 100644 index 00000000..469482e4 --- /dev/null +++ b/src/locker/lockscreen.cpp @@ -0,0 +1,102 @@ +#include +#include "glib.h" +#include "glibmm/main.h" +#include "locker.hpp" +#include "lockscreen.hpp" + + +WayfireLockerAppLockscreen::WayfireLockerAppLockscreen() +{ + grid = std::shared_ptr(new WayfireLockerGrid()); + set_child(revealer); + add_css_class("wf-locker"); + add_css_class("fade-in"); + revealer.set_transition_type(Gtk::RevealerTransitionType::CROSSFADE); + revealer.set_child(*grid); + grid->set_expand(true); + revealer.set_reveal_child(false); + + /* Mouse press or screen touch */ + auto click_gesture = Gtk::GestureClick::create(); + click_gesture->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); + signals.push_back(click_gesture->signal_released().connect([=] (int count, double x, double y) + { + start_disappear_timer(); + /* If we are hidden and have not started showing... */ + if(!revealer.get_reveal_child()) + { + revealer.set_reveal_child(true); + click_gesture->set_state(Gtk::EventSequenceState::CLAIMED); + } + })); + add_controller(click_gesture); + + /* Mouse movement */ + auto pointer_gesture = Gtk::EventControllerMotion::create(); + signals.push_back(pointer_gesture->signal_motion().connect([=] (double x, double y) + { + // Avoid first motion event and repeated with same location + int ix = x; + int iy = y; + if (last_x < 0 && last_y < 0) + { + last_x = ix; + last_y = iy; + return; + } + if (ix == last_x && iy == last_y) + { + return; + } + last_x = ix; + last_y = iy; + start_disappear_timer(); + if(!revealer.get_reveal_child()) + { + revealer.set_reveal_child(true); + } + })); + add_controller(pointer_gesture); + /* Keypress */ + auto typing_gesture = Gtk::EventControllerKey::create(); + typing_gesture->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); + signals.push_back(typing_gesture->signal_key_pressed().connect([=] (guint keyval, guint keycode, + Gdk::ModifierType state) + { + start_disappear_timer(); + if(!revealer.get_reveal_child()) + { + revealer.set_reveal_child(true); + return true; + } + return false; + }, false)); + add_controller(typing_gesture); +} + +void WayfireLockerAppLockscreen::start_disappear_timer() +{ + WayfireLockerApp::get().user_activity(); + if (timeout) + { + timeout.disconnect(); + } + if (hide_timeout>0) + { + timeout = Glib::signal_timeout().connect_seconds( + [this] () + { + revealer.set_reveal_child(false); + return G_SOURCE_REMOVE; + }, 5); + } +} + +void WayfireLockerAppLockscreen::disconnect() +{ + timeout.disconnect(); + for (auto signal : signals) + { + signal.disconnect(); + } +} \ No newline at end of file diff --git a/src/locker/lockscreen.hpp b/src/locker/lockscreen.hpp index c419c75f..9010f4e5 100644 --- a/src/locker/lockscreen.hpp +++ b/src/locker/lockscreen.hpp @@ -4,8 +4,6 @@ #include #include -#include "gtkmm/eventcontroller.h" -#include "gtkmm/gesture.h" #include "wf-option-wrap.hpp" #include "lockergrid.hpp" class WayfireLockerAppLockscreen: public Gtk::Window @@ -15,75 +13,11 @@ class WayfireLockerAppLockscreen: public Gtk::Window Gtk::Revealer revealer; sigc::connection timeout; WfOption hide_timeout {"locker/hide_time"}; + std::vector signals; + int last_x=-1, last_y=-1; - WayfireLockerAppLockscreen() - { - grid = std::shared_ptr(new WayfireLockerGrid()); - set_child(revealer); - add_css_class("wf-locker"); - revealer.set_transition_type(Gtk::RevealerTransitionType::CROSSFADE); - revealer.set_child(*grid); - grid->set_expand(true); - revealer.set_reveal_child(false); + WayfireLockerAppLockscreen(); - /* Mouse press or screen touch */ - auto click_gesture = Gtk::GestureClick::create(); - click_gesture->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); - click_gesture->signal_released().connect([=] (int count, double x, double y) - { - start_disappear_timer(); - /* If we are hidden and have not started showing... */ - if(!revealer.get_reveal_child()) - { - revealer.set_reveal_child(true); - click_gesture->set_state(Gtk::EventSequenceState::CLAIMED); - } - }); - add_controller(click_gesture); - - /* Mouse movement */ - auto pointer_gesture = Gtk::EventControllerMotion::create(); - pointer_gesture->signal_motion().connect([=] (double x, double y) - { - start_disappear_timer(); - /* If we are hidden and have not started showing... */ - if(!revealer.get_reveal_child()) - { - revealer.set_reveal_child(true); - } - }); - add_controller(pointer_gesture); - /* Keypress */ - auto typing_gesture = Gtk::EventControllerKey::create(); - typing_gesture->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); - typing_gesture->signal_key_pressed().connect([=] (guint keyval, guint keycode, - Gdk::ModifierType state) - { - start_disappear_timer(); - if(!revealer.get_reveal_child()) - { - revealer.set_reveal_child(true); - return true; - } - return false; - }, false); - add_controller(typing_gesture); - } - - void start_disappear_timer() - { - if (timeout) - { - timeout.disconnect(); - } - if (hide_timeout>0) - { - timeout = Glib::signal_timeout().connect_seconds( - [this] () - { - revealer.set_reveal_child(false); - return G_SOURCE_REMOVE; - }, 5); - } - } + void start_disappear_timer(); + void disconnect(); }; \ No newline at end of file diff --git a/src/locker/meson.build b/src/locker/meson.build index 93ac9b8d..9b2999bf 100644 --- a/src/locker/meson.build +++ b/src/locker/meson.build @@ -30,7 +30,7 @@ endif executable( 'wf-locker', - ['locker.cpp'] + widget_sources, + ['locker.cpp', 'lockscreen.cpp'] + widget_sources, dependencies: deps, install: true, ) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 2882bfb5..648b8691 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -100,7 +100,6 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrstart_fingerprint_scanning(); @@ -145,11 +144,12 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_sync("VerifyStop"); + stop_fingerprint_scanning(); } } else if (signal_name == "VerifyFingerSelected") { + /* TODO potentially present this to user to tell them + which fingerprint is being expected */ Glib::Variant finger_name; params.get_child(finger_name,0); std::cout << "Finger : " << finger_name.get() << std::endl; @@ -190,7 +190,10 @@ void WayfireLockerFingerprintPlugin::claim_device() void WayfireLockerFingerprintPlugin::release_device() { - device_proxy->call_sync("Release"); + if (device_proxy) + { + device_proxy->call_sync("Release"); + } } void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() @@ -199,12 +202,10 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() { return; } - - if (device_proxy && !is_scanning) + if (device_proxy) { show(); update_labels("Use fingerprint to unlock"); - is_scanning = true; device_proxy->call_sync("VerifyStart", nullptr, Glib::Variant>::create({""})); @@ -216,8 +217,22 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() void WayfireLockerFingerprintPlugin::stop_fingerprint_scanning() { - device_proxy->call_sync("VerifyStop"); - is_scanning = false; + if (starting_fingerprint){ + starting_fingerprint.disconnect(); + } + if (!device_proxy) + { + return; + } + /* Stop if running. Eventually log or respond to errors + but for now, avoid crashing lockscreen on close-down */ + try{ + device_proxy->call_sync("VerifyStop"); + } catch(Glib::Error & e) + { + + } + } void WayfireLockerFingerprintPlugin::init() @@ -256,10 +271,8 @@ void WayfireLockerFingerprintPlugin::init() void WayfireLockerFingerprintPlugin::deinit() { - if(is_scanning) - { - stop_fingerprint_scanning(); - } + // Ensure we return state to allow other programs to use scanner + stop_fingerprint_scanning(); release_device(); if(signal) { diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 2906a331..653a0c63 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -34,7 +34,7 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin void show(); sigc::connection signal; - bool is_scanning; + sigc::connection starting_fingerprint; bool show_state = false; void update_labels(std::string text); void update_image(std::string image); diff --git a/src/locker/plugin/instant.cpp b/src/locker/plugin/instant.cpp index a9999577..9d0a1830 100644 --- a/src/locker/plugin/instant.cpp +++ b/src/locker/plugin/instant.cpp @@ -22,7 +22,7 @@ void WayfireLockerInstantPlugin::add_output(int id, std::shared_ptrsignal_clicked().connect([] () { - WayfireLockerApp::get().perform_unlock(); + WayfireLockerApp::get().perform_unlock("Instant unlock pressed"); }, false); } diff --git a/src/locker/plugin/password.cpp b/src/locker/plugin/password.cpp index 0553b73e..f88f0a9e 100644 --- a/src/locker/plugin/password.cpp +++ b/src/locker/plugin/password.cpp @@ -146,7 +146,7 @@ void WayfireLockerPasswordPlugin::submit_user_password(std::string password) retval = pam_end(local_auth_handle, retval); if (unlock) { - WayfireLockerApp::get().perform_unlock(); + WayfireLockerApp::get().perform_unlock("PAM Password authenticated"); } } diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index 22f17e4a..e02fc413 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -194,7 +194,7 @@ void WayfireLockerPinPlugin::submit_pin() auto hash = sha512(pin); if (hash == pinhash) { - WayfireLockerApp::get().perform_unlock(); + WayfireLockerApp::get().perform_unlock("PIN Authenticated"); } pin = ""; diff --git a/src/util/wf-shell-app.cpp b/src/util/wf-shell-app.cpp index dc72fa07..e1265777 100644 --- a/src/util/wf-shell-app.cpp +++ b/src/util/wf-shell-app.cpp @@ -311,7 +311,7 @@ void WayfireShellApp::init_app() app->add_main_option_entry( sigc::mem_fun(*this, &WayfireShellApp::parse_cssfile), "css", 's', "css style directory to use", "directory"); - + this->command_line(); // Activate app after parsing command line app->signal_command_line().connect_notify([=] (auto&) { diff --git a/src/util/wf-shell-app.hpp b/src/util/wf-shell-app.hpp index 7cc4a5df..826a2cc6 100644 --- a/src/util/wf-shell-app.hpp +++ b/src/util/wf-shell-app.hpp @@ -79,6 +79,7 @@ class WayfireShellApp virtual std::string get_config_file(); virtual std::string get_css_config_dir(); virtual void run(int argc, char **argv); + virtual void command_line(){}; virtual void on_config_reload() {} From fbed63508a7c628dc8032136c92dc7aba2c0451d Mon Sep 17 00:00:00 2001 From: trigg Date: Tue, 27 Jan 2026 00:10:26 +0000 Subject: [PATCH 47/67] - Hide Weather if no file exists --- src/locker/plugin/weather.cpp | 26 ++++++++++++++++++++++++++ src/locker/plugin/weather.hpp | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/src/locker/plugin/weather.cpp b/src/locker/plugin/weather.cpp index d8dcf176..83205c81 100644 --- a/src/locker/plugin/weather.cpp +++ b/src/locker/plugin/weather.cpp @@ -34,6 +34,10 @@ void WayfireLockerWeatherPlugin::add_output(int id, std::shared_ptr(new Gtk::Box())); auto weather_widget = weather_widgets[id]; + if (!shown) + { + weather_widget->hide(); + } auto label = Gtk::Label(); label.add_css_class("weather"); label.set_markup(label_contents); @@ -69,8 +73,10 @@ void WayfireLockerWeatherPlugin::update_weather() if (doc == NULL) { std::cerr << "Error reading JSON file " << file_path << ": " << err.msg << std::endl; + hide(); return; } + show(); yyjson_val *root_obj = yyjson_doc_get_root(doc); @@ -116,3 +122,23 @@ void WayfireLockerWeatherPlugin::deinit() { timeout.disconnect(); } + +void WayfireLockerWeatherPlugin::hide() +{ + for (auto& it : weather_widgets) + { + it.second->hide(); + } + + shown = false; +} + +void WayfireLockerWeatherPlugin::show() +{ + for (auto& it : weather_widgets) + { + it.second->show(); + } + + shown = true; +} \ No newline at end of file diff --git a/src/locker/plugin/weather.hpp b/src/locker/plugin/weather.hpp index 694adbae..480e8534 100644 --- a/src/locker/plugin/weather.hpp +++ b/src/locker/plugin/weather.hpp @@ -20,7 +20,11 @@ class WayfireLockerWeatherPlugin : public WayfireLockerPlugin void update_icons(std::string path); void update_weather(); + void hide(); + void show(); + std::unordered_map> weather_widgets; std::string label_contents = ""; std::string icon_path = ""; + bool shown; }; From fa796b86084db732122ae566e38759b6e9627029 Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Mon, 26 Jan 2026 17:43:07 -0700 Subject: [PATCH 48/67] weather: Use wf-json instead of yyjson --- meson.build | 1 - src/locker/meson.build | 1 - src/locker/plugin/weather.cpp | 53 +++++++++++++++++------------------ 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/meson.build b/meson.build index bf8bf512..e472534f 100644 --- a/meson.build +++ b/meson.build @@ -28,7 +28,6 @@ libgvc = subproject('gvc', default_options: ['static=true'], required: get_optio xkbregistry = dependency('xkbregistry') json = subproject('wf-json').get_variable('wfjson') openssl = dependency('openssl') -yyjson = dependency('yyjson') if get_option('wayland-logout') == true wayland_logout = subproject('wayland-logout') diff --git a/src/locker/meson.build b/src/locker/meson.build index 9b2999bf..0c028f2f 100644 --- a/src/locker/meson.build +++ b/src/locker/meson.build @@ -20,7 +20,6 @@ deps = [ json, pam, openssl, - yyjson ] if libpulse.found() diff --git a/src/locker/plugin/weather.cpp b/src/locker/plugin/weather.cpp index 83205c81..77e1ef3e 100644 --- a/src/locker/plugin/weather.cpp +++ b/src/locker/plugin/weather.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -6,7 +7,7 @@ #include "lockergrid.hpp" #include "weather.hpp" -#include "yyjson.h" +#include "wayfire/nonstd/json.hpp" void WayfireLockerWeatherPlugin::update_labels(std::string text) @@ -65,42 +66,40 @@ void WayfireLockerWeatherPlugin::update_weather() std::string file_path = weather_data_dir + "/data.json"; - yyjson_read_flag flg = 0; - yyjson_read_err err; + std::ifstream input_file(file_path); - yyjson_doc *doc = yyjson_read_file(file_path.c_str(), flg, NULL, &err); - - if (doc == NULL) + if (!input_file) { - std::cerr << "Error reading JSON file " << file_path << ": " << err.msg << std::endl; + std::cerr << "Error reading json file " << file_path << std::endl; hide(); return; } - show(); - yyjson_val *root_obj = yyjson_doc_get_root(doc); + std::stringstream buf; + buf << input_file.rdbuf(); + + wf::json_t json_data; + + auto err = wf::json_t::parse_string(buf.str(), json_data); - if (root_obj && yyjson_is_obj(root_obj)) + if (err.has_value()) { - yyjson_obj_iter iter; - yyjson_obj_iter_init(root_obj, &iter); - yyjson_val *key, *val; - while ((key = yyjson_obj_iter_next(&iter))) - { - val = yyjson_obj_iter_get_val(key); - - if (yyjson_get_str(key) == std::string("temp")) - { - this->update_labels(yyjson_get_str(val)); - } else if (yyjson_get_str(key) == std::string("icon")) - { - update_icons(yyjson_get_str(val)); - } - } + std::cerr << "Error parsing json data " << file_path << ": " << *err << std::endl; + hide(); + return; } - yyjson_doc_free(doc); + if (!json_data.has_member("temp") || !json_data.has_member("icon")) + { + std::cerr << "Unexpected weather json data in " << file_path << std::endl; + hide(); + return; + } + update_labels(json_data["temp"]); + update_icons(json_data["icon"]); + + show(); } WayfireLockerWeatherPlugin::WayfireLockerWeatherPlugin(): @@ -141,4 +140,4 @@ void WayfireLockerWeatherPlugin::show() } shown = true; -} \ No newline at end of file +} From 5a9de24f7170f779ab86a37cc4a93e4641bf404b Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Mon, 26 Jan 2026 17:49:39 -0700 Subject: [PATCH 49/67] weather: Update default css --- data/css/default.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/css/default.css b/data/css/default.css index 9d4a7ce4..6233467e 100644 --- a/data/css/default.css +++ b/data/css/default.css @@ -156,7 +156,9 @@ revealer.wf-locker { -gtk-icon-size:96px; } .wf-locker image.weather { - -gtk-icon-size:150px; + -gtk-icon-size:80px; + padding-left: 25px; + padding-right: 25px; padding-bottom: 25px; } .wf-locker label.weather { From 4e90cba344effb124ca36a127957c75bcb70b140 Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Mon, 26 Jan 2026 18:15:54 -0700 Subject: [PATCH 50/67] weather: Update weather-fetch.py script --- data/weather-fetch.py | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/data/weather-fetch.py b/data/weather-fetch.py index ff13adbb..84ecfc9d 100644 --- a/data/weather-fetch.py +++ b/data/weather-fetch.py @@ -56,6 +56,7 @@ # -h, --help show this help message and exit # -l, --location LOCATION # -k, --apikey APIKEY +# -c, --classic-icons # -m, --metric # -d, --debug # @@ -93,6 +94,27 @@ import sys import os +icon_map = { + "01d": "1", # clear sky day + "01n": "33", # clear sky night + "02d": "2", # few clouds day + "02n": "34", # few clouds night + "03d": "3", # scattered clouds day + "03n": "35", # scattered clouds night + "04d": "4", # broken clouds day + "04n": "36", # broken clouds night + "09d": "14", # shower rain day + "09n": "39", # shower rain night + "10d": "13", # rain day + "10n": "40", # rain night + "11d": "16", # thunderstorm day + "11n": "42", # thunderstorm night + "13d": "23", # snow day + "13n": "44", # snow night + "50d": "5", # mist day + "50n": "37", # mist night +} + weather = {} def get_weather_info(): @@ -121,11 +143,16 @@ def get_weather_info(): else: weather["temperature"] = str(int(weather_data["main"]["temp"])) + "°F" weather_icon_code = weather_data["weather"][0]["icon"] - weather_icon_name = weather_icon_code + "@2x.png" + if weather["classic-icons"]: + weather_icon_name = weather_icon_code + "@2x.png" + weather_icon_url = "https://openweathermap.org/img/wn/" + weather_icon_name + else: + weather_icon_name = icon_map[weather_icon_code] + ".svg" + weather_icon_url = "https://www.accuweather.com/assets/images/weather-icons/v2a/" + weather_icon_name weather_icon_path = weather["icon_directory"] + "/" + weather_icon_name + print(f"Checking for icon {weather_icon_path}") if not os.path.exists(weather_icon_path): - weather_icon_url = "https://openweathermap.org/img/wn/" + weather_icon_name - img_data = requests.get(weather_icon_url).content + img_data = requests.get(weather_icon_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}).content with open(weather_icon_path, 'wb') as weather_icon: weather_icon.write(img_data) print(f"Weather information for {weather_data["name"]}, {weather_data["sys"]["country"]}: {weather["temperature"]} - {weather_data["weather"][0]["description"]}") @@ -148,6 +175,7 @@ def main(): epilog="Copyright (c) 2026 Scott Moreau ") parser.add_argument("-l", "--location") parser.add_argument("-k", "--apikey") + parser.add_argument("-c", "--classic-icons", action="store_true") parser.add_argument("-m", "--metric", action="store_true") parser.add_argument("-d", "--debug", action="store_true") args = parser.parse_args() @@ -159,6 +187,7 @@ def main(): exit(-1) weather["location_key"] = args.location weather["api_key"] = args.apikey + weather["classic-icons"] = args.classic_icons weather["metric_units"] = args.metric weather["debug"] = args.debug @@ -171,7 +200,7 @@ def main(): data_dir = Path(weather["data_directory"]) if not data_dir.exists(): data_dir.mkdir(parents=True, exist_ok=True) - + get_weather_info() if __name__ == "__main__": From ed6664b90474aec50d8b3a51f40596604d013d31 Mon Sep 17 00:00:00 2001 From: trigg Date: Tue, 27 Jan 2026 01:57:55 +0000 Subject: [PATCH 51/67] - theoretical fprintd hot unplug support --- src/locker/plugin/fingerprint.cpp | 56 ++++++++++++++++++++++--------- src/locker/plugin/fingerprint.hpp | 3 +- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 648b8691..b21b5564 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -47,24 +47,34 @@ void WayfireLockerFingerprintPlugin::on_connection(const Glib::RefPtr & result) { - auto manager_proxy = Gio::DBus::Proxy::create_finish(result); - 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? */ - { - hide(); - return; - } + manager_proxy = Gio::DBus::Proxy::create_finish(result); + get_device(); }); } +void WayfireLockerFingerprintPlugin::get_device() +{ + if (device_proxy != nullptr) + { + std::cerr << "get_device when device_proxy is not null" << std::endl; + return; + } + 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? */ + { + hide(); + return; + } +} + void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr & result) { device_proxy = Gio::DBus::Proxy::create_finish(result); @@ -140,6 +150,22 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrstart_fingerprint_scanning(); return G_SOURCE_REMOVE; }, 5); + } else if (mesg.get() == "verify-disconnected") + { + /* This needs testing on a machine with removable fprint reader */ + device_proxy = nullptr; + if (signal) + { + signal.disconnect(); + } + /* Delay, cools down a repeated failing loop */ + Glib::signal_timeout().connect_seconds( + [this] () { + get_device(); + return G_SOURCE_REMOVE; + }, 2 + ); + return; } if (is_done && device_proxy != nullptr) diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 653a0c63..47cc55ee 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -15,12 +15,13 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin { private: DBusConnection connection; - Glib::RefPtr device_proxy; + Glib::RefPtr device_proxy, manager_proxy; public: WayfireLockerFingerprintPlugin(); ~WayfireLockerFingerprintPlugin(); void on_connection(const Glib::RefPtr & connection, const Glib::ustring & name); + void get_device(); void on_device_acquired(const Glib::RefPtr & result); void claim_device(); void release_device(); From 3876634ef3da6c573dc1e211f98f9ef4cfb5df4c Mon Sep 17 00:00:00 2001 From: trigg Date: Tue, 27 Jan 2026 19:12:48 +0000 Subject: [PATCH 52/67] - Moved reveal from per-window to per-widget - Allow some widgets to remain through inactivity - MPRIS widget re-appears on track change - Allow each app to add extra Gtk application flags. --- metadata/locker.xml | 102 ++++++++++++++++++++++++++++-- src/locker/locker.cpp | 30 ++++----- src/locker/lockergrid.hpp | 23 +++++-- src/locker/lockscreen.cpp | 50 +++------------ src/locker/lockscreen.hpp | 3 +- src/locker/meson.build | 2 +- src/locker/plugin.hpp | 9 +-- src/locker/plugin/battery.cpp | 87 ++++++++++--------------- src/locker/plugin/battery.hpp | 16 +++-- src/locker/plugin/clock.cpp | 29 +++++---- src/locker/plugin/clock.hpp | 10 ++- src/locker/plugin/fingerprint.cpp | 66 ++++++++----------- src/locker/plugin/fingerprint.hpp | 17 ++++- src/locker/plugin/instant.cpp | 26 +++++--- src/locker/plugin/instant.hpp | 10 ++- src/locker/plugin/mpris.cpp | 32 ++++++---- src/locker/plugin/mpris.hpp | 24 +++++-- src/locker/plugin/password.cpp | 51 ++++++++------- src/locker/plugin/password.hpp | 14 +++- src/locker/plugin/pin.cpp | 59 +++++++++-------- src/locker/plugin/pin.hpp | 14 ++-- src/locker/plugin/user.cpp | 55 ++++++++-------- src/locker/plugin/user.hpp | 14 +++- src/locker/plugin/volume.cpp | 53 ++++++++-------- src/locker/plugin/volume.hpp | 14 +++- src/locker/plugin/weather.cpp | 35 +++++----- src/locker/plugin/weather.hpp | 14 +++- src/locker/timedrevealer.cpp | 94 +++++++++++++++++++++++++++ src/locker/timedrevealer.hpp | 18 ++++++ src/util/wf-shell-app.cpp | 2 +- 30 files changed, 618 insertions(+), 355 deletions(-) create mode 100644 src/locker/timedrevealer.cpp create mode 100644 src/locker/timedrevealer.hpp diff --git a/metadata/locker.xml b/metadata/locker.xml index 3707a8b3..e5ed9a9e 100644 --- a/metadata/locker.xml +++ b/metadata/locker.xml @@ -15,13 +15,65 @@ + + @@ -70,6 +122,10 @@ center-center + <_short>PIN @@ -125,6 +181,10 @@ <_short>Pin Reply Font 20pt default + <_short>Fingerprint @@ -180,6 +240,10 @@ <_short>Fingerprint Icon Size 128 + <_short>Clock @@ -230,6 +294,10 @@ top-center + + <_short>User @@ -334,6 +406,10 @@ <_short>Font 16pt default + <_short>Now Playing @@ -395,6 +471,10 @@ bottom-right + <_short>Battery @@ -470,8 +550,13 @@ 96 16 + + <_short>Volume - + <_short>Instant Unlock @@ -567,6 +655,10 @@ <_short>Font default + diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index f4547a89..9c08c087 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -13,7 +13,6 @@ #include #include "css-config.hpp" -#include "lockergrid.hpp" #include "lockscreen.hpp" #include "plugin/battery.hpp" #include "plugin/clock.hpp" @@ -47,7 +46,7 @@ WayfireLockerApp::~WayfireLockerApp() void WayfireLockerApp::perform_lock() { - + WayfireLockerApp::get().init_plugins(); if (is_debug()) { if(!m_is_locked) @@ -64,9 +63,6 @@ void WayfireLockerApp::perform_lock() /* Called before each activate */ void WayfireLockerApp::command_line() { - //virtual bool parse_cfgfile(const Glib::ustring & option_name, - /// const Glib::ustring & value, bool has_value) - can_early_wake = true; app->add_main_option_entry( [=](const Glib::ustring & option_name, const Glib::ustring & value, bool has_value){ @@ -95,12 +91,12 @@ void WayfireLockerApp::on_activate() } /* Set a timer for early-wake unlock */ WayfireShellApp::on_activate(); - Glib::signal_timeout().connect_seconds([this](){ + Glib::signal_timeout().connect([this](){ can_early_wake = false; return G_SOURCE_REMOVE; }, WfOption {"locker/prewake"}); /* TODO Hot config for this? */ - exit_on_unlock = WfOption{"locker/exit_on_unlock"}; + //exit_on_unlock = WfOption{"locker/exit_on_unlock"}; auto debug = Glib::getenv("WF_LOCKER_DEBUG"); if (debug == "1") @@ -128,7 +124,7 @@ void WayfireLockerApp::on_activate() 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/prewake", ".fade-in {animation-name: slowfade;animation-duration: ", "s; animation-timing-function: linear; animation-iteration-count: 1; animation-fill-mode: forwards;} @keyframes slowfade { from {opacity:0;} to {opacity:1;}}"); + new CssFromConfigInt("locker/prewake", ".fade-in {animation-name: slowfade;animation-duration: ", "ms; animation-timing-function: linear; animation-iteration-count: 1; animation-fill-mode: forwards;} @keyframes slowfade { from {opacity:0;} to {opacity:1;}}"); /* Init plugins */ plugins.emplace("clock", Plugin(new WayfireLockerClockPlugin())); @@ -312,6 +308,10 @@ bool WayfireLockerApp::is_locked() void WayfireLockerApp::set_is_locked(bool locked) { m_is_locked = locked; + if (!locked) + { + can_early_wake = true; // Reset state Before next activate + } } /* Starting point */ @@ -332,7 +332,6 @@ void on_session_locked_c(GtkSessionLockInstance *lock, void *data) { std::cout << "Session locked" << std::endl; WayfireLockerApp::get().set_is_locked(true); - WayfireLockerApp::get().init_plugins(); } void on_session_lock_failed_c(GtkSessionLockInstance *lock, void *data) @@ -353,15 +352,16 @@ void on_session_unlocked_c(GtkSessionLockInstance *lock, void *data) if (WayfireLockerApp::get().exit_on_unlock) { // Exiting too early causes a lock-out - Glib::signal_timeout().connect_seconds([] () -> bool + Glib::signal_idle().connect([] () -> bool { exit(0); },1); } - // Lose windows - WayfireLockerApp::get().window_list.clear(); - // Replace the lock object - //lock = gtk_session_lock_instance_new(); + // Lose windows, but not right away to avoid lock-screen-crash for 1 frame + Glib::signal_idle().connect([] () { + WayfireLockerApp::get().window_list.clear(); + return G_SOURCE_REMOVE; + }); } void on_monitor_present_c(GtkSessionLockInstance *lock, GdkMonitor *monitor, void *data) diff --git a/src/locker/lockergrid.hpp b/src/locker/lockergrid.hpp index fed39103..e154013f 100644 --- a/src/locker/lockergrid.hpp +++ b/src/locker/lockergrid.hpp @@ -3,7 +3,9 @@ #include #include #include -#include + +#include "timedrevealer.hpp" + class WayfireLockerGrid : public Gtk::CenterBox { @@ -11,8 +13,19 @@ class WayfireLockerGrid : public Gtk::CenterBox Gtk::Box box[9]; public: - - void remove(Gtk::Widget & widget) + void window_activity() + { + for (int count = 0; count < 9; count++) + { + for (auto child = box[count].get_first_child(); child!=nullptr; child = child->get_next_sibling()) + { + auto cast_child = (WayfireLockerTimedRevealer*) child; + cast_child->activity(); + } + } + } + + void remove(WayfireLockerTimedRevealer & widget) { for (int count = 0; count < 9; count++) { @@ -25,7 +38,7 @@ class WayfireLockerGrid : public Gtk::CenterBox } } /* Config string to box from grid */ - void attach(Gtk::Widget & widget, std::string pos_string) + void attach(WayfireLockerTimedRevealer & widget, std::string pos_string) { if (pos_string == "top-left") { @@ -60,7 +73,7 @@ class WayfireLockerGrid : public Gtk::CenterBox } } - void attach(Gtk::Widget & widget, int col, int row) + void attach(WayfireLockerTimedRevealer & widget, int col, int row) { if ((col > 2) || (row > 2) || (col < 0) || (row < 0)) { diff --git a/src/locker/lockscreen.cpp b/src/locker/lockscreen.cpp index 469482e4..c654e353 100644 --- a/src/locker/lockscreen.cpp +++ b/src/locker/lockscreen.cpp @@ -1,6 +1,3 @@ -#include -#include "glib.h" -#include "glibmm/main.h" #include "locker.hpp" #include "lockscreen.hpp" @@ -8,26 +5,17 @@ WayfireLockerAppLockscreen::WayfireLockerAppLockscreen() { grid = std::shared_ptr(new WayfireLockerGrid()); - set_child(revealer); + set_child(*grid); add_css_class("wf-locker"); add_css_class("fade-in"); - revealer.set_transition_type(Gtk::RevealerTransitionType::CROSSFADE); - revealer.set_child(*grid); grid->set_expand(true); - revealer.set_reveal_child(false); /* Mouse press or screen touch */ auto click_gesture = Gtk::GestureClick::create(); click_gesture->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); signals.push_back(click_gesture->signal_released().connect([=] (int count, double x, double y) { - start_disappear_timer(); - /* If we are hidden and have not started showing... */ - if(!revealer.get_reveal_child()) - { - revealer.set_reveal_child(true); - click_gesture->set_state(Gtk::EventSequenceState::CLAIMED); - } + window_activity(); })); add_controller(click_gesture); @@ -50,11 +38,7 @@ WayfireLockerAppLockscreen::WayfireLockerAppLockscreen() } last_x = ix; last_y = iy; - start_disappear_timer(); - if(!revealer.get_reveal_child()) - { - revealer.set_reveal_child(true); - } + window_activity(); })); add_controller(pointer_gesture); /* Keypress */ @@ -63,38 +47,22 @@ WayfireLockerAppLockscreen::WayfireLockerAppLockscreen() signals.push_back(typing_gesture->signal_key_pressed().connect([=] (guint keyval, guint keycode, Gdk::ModifierType state) { - start_disappear_timer(); - if(!revealer.get_reveal_child()) - { - revealer.set_reveal_child(true); - return true; - } + window_activity(); return false; }, false)); add_controller(typing_gesture); } -void WayfireLockerAppLockscreen::start_disappear_timer() + +void WayfireLockerAppLockscreen::window_activity() { + // Alert entire locker, in case of pre-wake WayfireLockerApp::get().user_activity(); - if (timeout) - { - timeout.disconnect(); - } - if (hide_timeout>0) - { - timeout = Glib::signal_timeout().connect_seconds( - [this] () - { - revealer.set_reveal_child(false); - return G_SOURCE_REMOVE; - }, 5); - } + // Alert all widgets in window, to reveal themselves + grid->window_activity(); } - void WayfireLockerAppLockscreen::disconnect() { - timeout.disconnect(); for (auto signal : signals) { signal.disconnect(); diff --git a/src/locker/lockscreen.hpp b/src/locker/lockscreen.hpp index 9010f4e5..6b425c4f 100644 --- a/src/locker/lockscreen.hpp +++ b/src/locker/lockscreen.hpp @@ -10,7 +10,6 @@ class WayfireLockerAppLockscreen: public Gtk::Window { public: std::shared_ptr grid; - Gtk::Revealer revealer; sigc::connection timeout; WfOption hide_timeout {"locker/hide_time"}; std::vector signals; @@ -20,4 +19,6 @@ class WayfireLockerAppLockscreen: public Gtk::Window void start_disappear_timer(); void disconnect(); + + void window_activity(); }; \ No newline at end of file diff --git a/src/locker/meson.build b/src/locker/meson.build index 0c028f2f..8e68afaa 100644 --- a/src/locker/meson.build +++ b/src/locker/meson.build @@ -29,7 +29,7 @@ endif executable( 'wf-locker', - ['locker.cpp', 'lockscreen.cpp'] + widget_sources, + ['locker.cpp', 'lockscreen.cpp', 'timedrevealer.cpp'] + widget_sources, dependencies: deps, install: true, ) diff --git a/src/locker/plugin.hpp b/src/locker/plugin.hpp index e9f76d5c..61e0e44b 100644 --- a/src/locker/plugin.hpp +++ b/src/locker/plugin.hpp @@ -13,11 +13,12 @@ class WayfireLockerPlugin { public: - WayfireLockerPlugin(std::string option_name, std::string position_name): - enable(WfOption{option_name}), - position(WfOption{position_name}) + WayfireLockerPlugin(std::string prefix): + enable(WfOption{prefix+"_enable"}), + always(WfOption{prefix+"_always"}), + position(WfOption{prefix+"_position"}) {}; - WfOption enable; + WfOption enable, always; WfOption position; virtual void add_output(int id, std::shared_ptr grid) = 0; virtual void remove_output(int id, std::shared_ptr grid) = 0; diff --git a/src/locker/plugin/battery.cpp b/src/locker/plugin/battery.cpp index a5013412..1dc901c0 100644 --- a/src/locker/plugin/battery.cpp +++ b/src/locker/plugin/battery.cpp @@ -2,8 +2,10 @@ #include #include #include +#include #include "lockergrid.hpp" +#include "timedrevealer.hpp" #include "battery.hpp" @@ -62,17 +64,17 @@ static std::string uint_to_time(int64_t time) void WayfireLockerBatteryPlugin::update_percentages(std::string text) { - for (auto& it : labels) + for (auto& it : widgets) { - it.second->set_label(text); + it.second->label.set_label(text); } } void WayfireLockerBatteryPlugin::update_descriptions(std::string text) { - for (auto& it : subtexts) + for (auto& it : widgets) { - it.second->set_label(text); + it.second->subtext.set_label(text); } } @@ -80,50 +82,45 @@ void WayfireLockerBatteryPlugin::update_images() { Glib::Variant icon_name; display_device->get_cached_property(icon_name, ICON); - for (auto& it : images) + for (auto& it : widgets) { - it.second->set_from_icon_name(icon_name.get()); + it.second->image.set_from_icon_name(icon_name.get()); } } +WayfireLockerBatteryPluginWidget::WayfireLockerBatteryPluginWidget(): + WayfireLockerTimedRevealer("locker/battery_always") +{ + set_child(grid); + label.add_css_class("battery-percent"); + subtext.add_css_class("battery-description"); + image.add_css_class("battery-image"); + + grid.attach(image, 0, 0); + grid.attach(label, 1, 0); + grid.attach(subtext, 0, 1, 2, 1); + + +} + void WayfireLockerBatteryPlugin::add_output(int id, std::shared_ptr grid) { - grids.emplace(id, std::shared_ptr(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 batt_grid = grids[id]; - auto label = labels[id]; - auto subtext = subtexts[id]; - auto image = images[id]; + widgets.emplace(id, new WayfireLockerBatteryPluginWidget()); + auto widget = widgets[id]; if (!show_state) { - label->hide(); - subtext->hide(); - image->hide(); + widget->hide(); } - - 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); - - grid->attach(*batt_grid, (std::string)position); + grid->attach(*widget, (std::string)position); update_details(); } void WayfireLockerBatteryPlugin::remove_output(int id, std::shared_ptr grid) { - grid->remove(*grids[id]); - grids.erase(id); - labels.erase(id); - subtexts.erase(id); - images.erase(id); + grid->remove(*widgets[id]); + widgets.erase(id); } void WayfireLockerBatteryPlugin::init() @@ -266,17 +263,7 @@ void WayfireLockerBatteryPlugin::update_details() void WayfireLockerBatteryPlugin::hide() { show_state = false; - for (auto& it : labels) - { - it.second->hide(); - } - - for (auto& it : images) - { - it.second->hide(); - } - - for (auto & it : subtexts) + for (auto& it : widgets) { it.second->hide(); } @@ -285,22 +272,12 @@ void WayfireLockerBatteryPlugin::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) + for (auto& it : widgets) { it.second->show(); } } WayfireLockerBatteryPlugin::WayfireLockerBatteryPlugin(): - WayfireLockerPlugin("locker/battery_enable", "locker/battery_position") + WayfireLockerPlugin("locker/battery") { } \ No newline at end of file diff --git a/src/locker/plugin/battery.hpp b/src/locker/plugin/battery.hpp index 388fff0c..d1983aab 100644 --- a/src/locker/plugin/battery.hpp +++ b/src/locker/plugin/battery.hpp @@ -8,6 +8,7 @@ #include "plugin.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" using DBusConnection = Glib::RefPtr; using DBusProxy = Glib::RefPtr; @@ -24,6 +25,15 @@ using DBusProxy = Glib::RefPtr; #define TIMETOEMPTY "TimeToEmpty" #define SHOULD_DISPLAY "IsPresent" +class WayfireLockerBatteryPluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Grid grid; + Gtk::Image image; + Gtk::Label label, subtext; + WayfireLockerBatteryPluginWidget(); +}; + class WayfireLockerBatteryPlugin : public WayfireLockerPlugin { private: @@ -50,8 +60,6 @@ class WayfireLockerBatteryPlugin : public WayfireLockerPlugin void update_images(); void update_details(); - std::map> images; - std::map> subtexts; - std::map> labels; - std::map> grids; + + std::map> widgets; }; diff --git a/src/locker/plugin/clock.cpp b/src/locker/plugin/clock.cpp index d0a5cdd1..20d03dba 100644 --- a/src/locker/plugin/clock.cpp +++ b/src/locker/plugin/clock.cpp @@ -3,34 +3,41 @@ #include #include "lockergrid.hpp" +#include "timedrevealer.hpp" #include "clock.hpp" void WayfireLockerClockPlugin::update_labels(std::string text) { - for (auto& it : labels) + for (auto& it : widgets) { - it.second->set_markup(text); + it.second->label.set_markup(text); } label_contents = text; } +WayfireLockerClockPluginWidget::WayfireLockerClockPluginWidget(std::string contents): + WayfireLockerTimedRevealer("locker/clock_always") +{ + set_child(label); + label.add_css_class("clock"); + label.set_markup(contents); + label.set_justify(Gtk::Justification::CENTER); +} + void WayfireLockerClockPlugin::add_output(int id, std::shared_ptr grid) { - labels.emplace(id, std::shared_ptr(new Gtk::Label())); - auto label = labels[id]; - label->add_css_class("clock"); - label->set_markup(label_contents); - label->set_justify(Gtk::Justification::CENTER); + widgets.emplace(id, new WayfireLockerClockPluginWidget(label_contents)); + auto widget = widgets[id]; - grid->attach(*label, position); + grid->attach(*widget, position); } void WayfireLockerClockPlugin::remove_output(int id, std::shared_ptr grid) { - grid->remove(*labels[id]); - labels.erase(id); + grid->remove(*widgets[id]); + widgets.erase(id); } void WayfireLockerClockPlugin::update_time() @@ -54,7 +61,7 @@ void WayfireLockerClockPlugin::update_time() } WayfireLockerClockPlugin::WayfireLockerClockPlugin(): - WayfireLockerPlugin("locker/clock_enable", "locker/clock_position") + WayfireLockerPlugin("locker/clock") {} void WayfireLockerClockPlugin::init() diff --git a/src/locker/plugin/clock.hpp b/src/locker/plugin/clock.hpp index 465b7139..69a79380 100644 --- a/src/locker/plugin/clock.hpp +++ b/src/locker/plugin/clock.hpp @@ -3,9 +3,17 @@ #include #include "plugin.hpp" +#include "timedrevealer.hpp" #include "wf-option-wrap.hpp" #include "lockergrid.hpp" +class WayfireLockerClockPluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Label label; + WayfireLockerClockPluginWidget(std::string contents); +}; + class WayfireLockerClockPlugin : public WayfireLockerPlugin { public: @@ -21,6 +29,6 @@ class WayfireLockerClockPlugin : public WayfireLockerPlugin void update_labels(std::string text); void update_time(); - std::unordered_map> labels; + std::unordered_map> widgets; std::string label_contents = ""; }; diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index b21b5564..7de1443e 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -11,6 +11,7 @@ #include "locker.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" #include "fingerprint.hpp" /** @@ -21,7 +22,7 @@ */ WayfireLockerFingerprintPlugin::WayfireLockerFingerprintPlugin() : - WayfireLockerPlugin("locker/fingerprint_enable", "locker/fingerprint_position") + WayfireLockerPlugin("locker/fingerprint") {} WayfireLockerFingerprintPlugin::~WayfireLockerFingerprintPlugin() @@ -307,43 +308,42 @@ void WayfireLockerFingerprintPlugin::deinit() device_proxy = nullptr; } -void WayfireLockerFingerprintPlugin::add_output(int id, std::shared_ptr grid) +WayfireLockerFingerprintPluginWidget::WayfireLockerFingerprintPluginWidget(std::string label_contents, std::string image_contents): + WayfireLockerTimedRevealer("locker/fingerprint_always") { - 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]; + set_child(box); + image.set_from_icon_name(image_contents); + label.set_label(label_contents); + + image.add_css_class("fingerprint-icon"); + label.add_css_class("fingerprint-text"); + box.set_orientation(Gtk::Orientation::VERTICAL); + box.append(image); + box.append(label); +} +void WayfireLockerFingerprintPlugin::add_output(int id, std::shared_ptr grid) +{ + widgets.emplace(id, new WayfireLockerFingerprintPluginWidget(label_contents, icon_contents)); + auto widget = widgets[id]; if (!show_state) { - image->hide(); - label->hide(); + widget->hide(); } - - 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"); - - grid->attach(*image, position); - grid->attach(*label, position); + grid->attach(*widget, position); } void WayfireLockerFingerprintPlugin::remove_output(int id, std::shared_ptr grid) { - grid->remove(*labels[id]); - grid->remove(*images[id]); - labels.erase(id); - images.erase(id); + grid->remove(*widgets[id]); + widgets.erase(id); } void WayfireLockerFingerprintPlugin::update_image(std::string image) { - for (auto& it : images) + for (auto& it : widgets) { - it.second->set_from_icon_name(image); + it.second->image.set_from_icon_name(image); } icon_contents = image; @@ -351,9 +351,9 @@ void WayfireLockerFingerprintPlugin::update_image(std::string image) void WayfireLockerFingerprintPlugin::update_labels(std::string text) { - for (auto& it : labels) + for (auto& it : widgets) { - it.second->set_label(text); + it.second->label.set_label(text); } label_contents = text; @@ -362,12 +362,7 @@ void WayfireLockerFingerprintPlugin::update_labels(std::string text) void WayfireLockerFingerprintPlugin::hide() { show_state = false; - for (auto& it : labels) - { - it.second->hide(); - } - - for (auto& it : images) + for (auto &it : widgets) { it.second->hide(); } @@ -376,12 +371,7 @@ void WayfireLockerFingerprintPlugin::hide() void WayfireLockerFingerprintPlugin::show() { show_state = true; - for (auto& it : labels) - { - it.second->show(); - } - - for (auto& it : images) + for (auto &it : widgets) { it.second->show(); } diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 47cc55ee..68c7309f 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include #include @@ -9,8 +9,20 @@ #include "lockergrid.hpp" #include "plugin.hpp" +#include "timedrevealer.hpp" + using DBusConnection = Glib::RefPtr; using DBusProxy = Glib::RefPtr; + +class WayfireLockerFingerprintPluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Box box; + Gtk::Image image; + Gtk::Label label; + WayfireLockerFingerprintPluginWidget(std::string label_contents, std::string image_contents); +}; + class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin { private: @@ -40,8 +52,7 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin void update_labels(std::string text); void update_image(std::string image); - std::unordered_map> labels; - std::unordered_map> images; + std::map> widgets; std::string icon_contents = ""; std::string label_contents = ""; }; diff --git a/src/locker/plugin/instant.cpp b/src/locker/plugin/instant.cpp index 9d0a1830..2c7a003b 100644 --- a/src/locker/plugin/instant.cpp +++ b/src/locker/plugin/instant.cpp @@ -5,22 +5,28 @@ #include "locker.hpp" #include "lockergrid.hpp" #include "plugin.hpp" +#include "timedrevealer.hpp" #include "instant.hpp" WayfireLockerInstantPlugin::WayfireLockerInstantPlugin(): - WayfireLockerPlugin("locker/instant_unlock_enable", "locker/instant_unlock_position") + WayfireLockerPlugin("locker/instant_unlock") { } -void WayfireLockerInstantPlugin::add_output(int id, std::shared_ptr grid) +WayfireLockerInstantPluginWidget::WayfireLockerInstantPluginWidget(): + WayfireLockerTimedRevealer("locker/instant_unlock_always") { - 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"); + set_child(button); + button.set_label("Unlock now"); + button.add_css_class("instant-unlock"); +} - grid->attach(*button, position); +void WayfireLockerInstantPlugin::add_output(int id, std::shared_ptr grid) +{ + widgets.emplace(id, new WayfireLockerInstantPluginWidget()); + auto widget = widgets[id]; + grid->attach(*widget, position); - button->signal_clicked().connect([] () + widget->button.signal_clicked().connect([] () { WayfireLockerApp::get().perform_unlock("Instant unlock pressed"); }, false); @@ -28,8 +34,8 @@ void WayfireLockerInstantPlugin::add_output(int id, std::shared_ptr grid) { - grid->remove(*buttons[id]); - buttons.erase(id); + grid->remove(*widgets[id]); + widgets.erase(id); } void WayfireLockerInstantPlugin::init() diff --git a/src/locker/plugin/instant.hpp b/src/locker/plugin/instant.hpp index 50916a65..78f55a5d 100644 --- a/src/locker/plugin/instant.hpp +++ b/src/locker/plugin/instant.hpp @@ -3,6 +3,14 @@ #include "plugin.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" + +class WayfireLockerInstantPluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Button button; + WayfireLockerInstantPluginWidget(); +}; class WayfireLockerInstantPlugin : public WayfireLockerPlugin { @@ -13,5 +21,5 @@ class WayfireLockerInstantPlugin : public WayfireLockerPlugin void init() override; void deinit() override; - std::unordered_map> buttons; + std::unordered_map> widgets; }; diff --git a/src/locker/plugin/mpris.cpp b/src/locker/plugin/mpris.cpp index 49731204..1ae573d6 100644 --- a/src/locker/plugin/mpris.cpp +++ b/src/locker/plugin/mpris.cpp @@ -12,9 +12,11 @@ /* Widget of controls for one player on one screen * https://specifications.freedesktop.org/mpris/latest/index.html */ WayfireLockerMPRISWidget::WayfireLockerMPRISWidget(std::string name, - Glib::RefPtr proxy) : proxy(proxy), name(name) + Glib::RefPtr proxy) : + WayfireLockerTimedRevealer("locker/mpris_always"), + proxy(proxy), + name(name) { - set_transition_type(Gtk::RevealerTransitionType::SLIDE_UP); image.add_css_class("albumart"); add_css_class("mpris"); @@ -136,13 +138,7 @@ WayfireLockerMPRISWidget::~WayfireLockerMPRISWidget() void WayfireLockerMPRISWidget::playbackstatus(std::string value) { - if (value == "Stopped") - { - set_reveal_child(false); - } else - { - set_reveal_child(true); - } + activity(); } /* https://www.freedesktop.org/wiki/Specifications/mpris-spec/metadata/ */ @@ -196,6 +192,7 @@ void WayfireLockerMPRISWidget::metadata(std::map Glib::ustring output = substitute_strings(pairs, (std::string)WfOption{"locker/mpris_format"}); label.set_label(output); + activity(); } void WayfireLockerMPRISWidget::cangonext(bool value) @@ -233,18 +230,18 @@ void WayfireLockerMPRISWidget::cancontrol(bool value) void WayfireLockerMPRISCollective::add_child(std::string id, Glib::RefPtr proxy) { - children.emplace(id, Glib::RefPtr(new WayfireLockerMPRISWidget(id, proxy))); - append(*children[id]); + children.emplace(id, new WayfireLockerMPRISWidget(id, proxy)); + box.append(*children[id]); } void WayfireLockerMPRISCollective::rem_child(std::string id) { - remove(*children[id]); + box.remove(*children[id]); children.erase(id); } WayfireLockerMPRISPlugin::WayfireLockerMPRISPlugin() : - WayfireLockerPlugin("locker/mpris_enable", "locker/mpris_position") + WayfireLockerPlugin("locker/mpris") { } void WayfireLockerMPRISPlugin::init() @@ -374,3 +371,12 @@ void WayfireLockerMPRISPlugin::rem_client(std::string path) it.second->rem_child(path); } } + +void WayfireLockerMPRISCollective::activity() +{ + set_reveal_child(true); + for (auto &it : children) + { + it.second->activity(); + } +} \ No newline at end of file diff --git a/src/locker/plugin/mpris.hpp b/src/locker/plugin/mpris.hpp index 8733df70..1388d3d0 100644 --- a/src/locker/plugin/mpris.hpp +++ b/src/locker/plugin/mpris.hpp @@ -5,17 +5,20 @@ #include #include #include +#include +#include "glib.h" +#include "glibmm/main.h" #include "plugin.hpp" #include "lockergrid.hpp" -#include "sigc++/connection.h" +#include "timedrevealer.hpp" std::string substitute_string(const std::string from, const std::string to, const std::string in); std::string substitute_strings(const std::vector> pairs, const std::string in); -class WayfireLockerMPRISWidget : public Gtk::Revealer +class WayfireLockerMPRISWidget : public WayfireLockerTimedRevealer { private: Glib::RefPtr proxy; @@ -27,6 +30,7 @@ class WayfireLockerMPRISWidget : public Gtk::Revealer void cancontrol(bool value); std::vector signals; + public: Gtk::Label label; Gtk::Button next, prev, playpause, kill; @@ -36,20 +40,30 @@ class WayfireLockerMPRISWidget : public Gtk::Revealer WayfireLockerMPRISWidget(std::string name, Glib::RefPtr proxy); ~WayfireLockerMPRISWidget(); + }; -class WayfireLockerMPRISCollective : public Gtk::Box +class WayfireLockerMPRISCollective : public WayfireLockerTimedRevealer { private: std::map> children; + Gtk::Box box; public: void add_child(std::string name, Glib::RefPtr proxy); void rem_child(std::string name); - WayfireLockerMPRISCollective() + WayfireLockerMPRISCollective(): + WayfireLockerTimedRevealer("locker/mpris_always") { - set_orientation(Gtk::Orientation::VERTICAL); + /* At next chance, force visibility */ + Glib::signal_idle().connect([this] () { + set_reveal_child(true); + return G_SOURCE_REMOVE; + }); + set_child(box); + box.set_orientation(Gtk::Orientation::VERTICAL); } + void activity() override; }; class WayfireLockerMPRISPlugin : public WayfireLockerPlugin diff --git a/src/locker/plugin/password.cpp b/src/locker/plugin/password.cpp index f88f0a9e..df1b47cf 100644 --- a/src/locker/plugin/password.cpp +++ b/src/locker/plugin/password.cpp @@ -2,6 +2,7 @@ #include #include #include "gtkmm/entry.h" +#include "gtkmm/enums.h" #include "gtkmm/label.h" #include #include @@ -10,14 +11,15 @@ #include "locker.hpp" #include "lockergrid.hpp" #include "plugin.hpp" +#include "timedrevealer.hpp" #include "password.hpp" void WayfireLockerPasswordPlugin::update_labels(std::string text) { - for (auto& it : labels) + for (auto& it : widgets) { - it.second->set_label(text); + it.second->label.set_label(text); } label_contents = text; @@ -25,47 +27,52 @@ void WayfireLockerPasswordPlugin::update_labels(std::string text) void WayfireLockerPasswordPlugin::blank_passwords() { - for (auto& it : entries) + for (auto& it : widgets) { - it.second->set_text(""); + it.second->entry.set_text(""); } } void WayfireLockerPasswordPlugin::add_output(int id, std::shared_ptr 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); + widgets.emplace(id, new WayfireLockerPasswordPluginWidget(label_contents)); + auto widget = widgets[id]; + /* Set entry callback for return */ - entry->signal_activate().connect([this, entry] () + widget->entry.signal_activate().connect([this, widget] () { - auto password = entry->get_text(); + auto password = widget->entry.get_text(); if (password.length() > 0) { submit_user_password(password); } }, true); /* Add to window */ - grid->attach(*entry, position); - grid->attach(*label, position); + grid->attach(*widget, position); +} + +WayfireLockerPasswordPluginWidget::WayfireLockerPasswordPluginWidget(std::string label_contents): + WayfireLockerTimedRevealer("locker/password_always") +{ + set_child(box); + box.append(entry); + box.append(label); + box.set_orientation(Gtk::Orientation::VERTICAL); + 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); } void WayfireLockerPasswordPlugin::remove_output(int id, std::shared_ptr grid) { - grid->remove(*entries[id]); - grid->remove(*labels[id]); - labels.erase(id); - entries.erase(id); + grid->remove(*widgets[id]); + widgets.erase(id); } WayfireLockerPasswordPlugin::WayfireLockerPasswordPlugin(): - WayfireLockerPlugin("locker/password_enable", "locker/password_position") + WayfireLockerPlugin("locker/password") { } /* PAM password C code... */ diff --git a/src/locker/plugin/password.hpp b/src/locker/plugin/password.hpp index 6c5807d9..77692911 100644 --- a/src/locker/plugin/password.hpp +++ b/src/locker/plugin/password.hpp @@ -1,14 +1,25 @@ #pragma once #include #include +#include #include #include "plugin.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); +class WayfireLockerPasswordPluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Box box; + Gtk::Entry entry; + Gtk::Label label; + WayfireLockerPasswordPluginWidget(std::string label_contents); +}; + class WayfireLockerPasswordPlugin : public WayfireLockerPlugin { public: @@ -23,8 +34,7 @@ class WayfireLockerPasswordPlugin : public WayfireLockerPlugin sigc::connection timeout; void update_labels(std::string text); - std::unordered_map> labels; - std::unordered_map> entries; + std::unordered_map> widgets; std::string label_contents = ""; std::string submitted_password = ""; }; diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index e02fc413..9a129786 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -14,6 +14,7 @@ #include "plugin.hpp" #include "locker.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" #include "pin.hpp" @@ -25,7 +26,8 @@ * and any non-digit will render it impossible to unlock. */ -PinPad::PinPad() +WayfireLockerPinPluginWidget::WayfireLockerPinPluginWidget(): + WayfireLockerTimedRevealer("locker/pin_always") { for (int count = 0; count < 10; count++) { @@ -65,42 +67,40 @@ PinPad::PinPad() label.add_css_class("pinpad-current"); } -PinPad::~PinPad() +WayfireLockerPinPluginWidget::~WayfireLockerPinPluginWidget() {} -void PinPad::init() +void WayfireLockerPinPluginWidget::init(std::string label_text) { - 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); + set_child(grid); + grid.add_css_class("pinpad"); + grid.attach(label, 0, 0, 3); + grid.attach(numbers[1], 0, 1); + grid.attach(numbers[2], 1, 1); + grid.attach(numbers[3], 2, 1); + grid.attach(numbers[4], 0, 2); + grid.attach(numbers[5], 1, 2); + grid.attach(numbers[6], 2, 2); + grid.attach(numbers[7], 0, 3); + grid.attach(numbers[8], 1, 3); + grid.attach(numbers[9], 2, 3); + grid.attach(bsub, 2, 4); + grid.attach(numbers[0], 1, 4); + grid.attach(bcan, 0, 4); + grid.set_vexpand(true); + grid.set_column_homogeneous(true); + grid.set_row_homogeneous(true); + label.set_text(label_text); } WayfireLockerPinPlugin::WayfireLockerPinPlugin(): - WayfireLockerPlugin("locker/pin_enable", "locker/pin_position") + WayfireLockerPlugin("locker/pin") { + /* TODO Watch for file changes and update in-memory hash */ if (!enable) { return; } - - /* TODO ... */ - // if (cmdline_config.has_value()) - // { - // return cmdline_config.value(); - // } std::string config_dir; char *config_home = getenv("XDG_CONFIG_HOME"); @@ -150,12 +150,11 @@ void WayfireLockerPinPlugin::add_output(int id, std::shared_ptradd_css_class("pinpad"); - pinpad->init(); + std::string asterisks(pin.length(), '*'); + pinpad->init(asterisks); grid->attach(*pinpad, position); - update_labels(); /* Update all to set this one? maybe overkill */ } void WayfireLockerPinPlugin::remove_output(int id, std::shared_ptr grid) diff --git a/src/locker/plugin/pin.hpp b/src/locker/plugin/pin.hpp index 1d805922..6d0699f3 100644 --- a/src/locker/plugin/pin.hpp +++ b/src/locker/plugin/pin.hpp @@ -7,17 +7,17 @@ #include "../plugin.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" -/* Rather than keep an unordered list for each widget, put them together */ -class WayfireLockerPinPlugin; -class PinPad : public Gtk::Grid +class WayfireLockerPinPluginWidget : public WayfireLockerTimedRevealer { public: - PinPad(); - ~PinPad(); + WayfireLockerPinPluginWidget(); + ~WayfireLockerPinPluginWidget(); + Gtk::Grid grid; Gtk::Button bsub, bcan; Gtk::Label label; - void init(); + void init(std::string label); void check(); Gtk::Button numbers[10]; }; @@ -38,7 +38,7 @@ class WayfireLockerPinPlugin : public WayfireLockerPlugin void add_digit(std::string digit); std::string sha512(const std::string input); - std::unordered_map> pinpads; + std::unordered_map> pinpads; std::string pin = ""; std::string pinhash = "nope"; diff --git a/src/locker/plugin/user.cpp b/src/locker/plugin/user.cpp index 27fd489c..c086853e 100644 --- a/src/locker/plugin/user.cpp +++ b/src/locker/plugin/user.cpp @@ -2,10 +2,11 @@ #include "lockergrid.hpp" #include "plugin.hpp" +#include "timedrevealer.hpp" #include "user.hpp" WayfireLockerUserPlugin::WayfireLockerUserPlugin(): - WayfireLockerPlugin("locker/user_enable", "locker/user_position") + WayfireLockerPlugin("locker/user") {} void WayfireLockerUserPlugin::init() @@ -34,6 +35,7 @@ void WayfireLockerUserPlugin::init() struct stat sb; if ((stat(home_path_file.c_str(), &sb) == 0) && !(sb.st_mode & S_IFDIR)) { + std::cout << "Chosen image "< grid) +WayfireLockerUserPluginWidget::WayfireLockerUserPluginWidget(std::string image_path): + WayfireLockerTimedRevealer("locker/user_always") { - labels.emplace(id, Glib::RefPtr(new Gtk::Label())); - images.emplace(id, Glib::RefPtr(new Gtk::Image())); - boxes.emplace(id, Glib::RefPtr(new Gtk::Box)); - - auto label = labels[id]; - auto image = images[id]; - auto box = boxes[id]; - - box->add_css_class("user"); - box->set_orientation(Gtk::Orientation::VERTICAL); - image->set_halign(Gtk::Align::CENTER); - image->set_valign(Gtk::Align::END); - label->set_halign(Gtk::Align::CENTER); - label->set_valign(Gtk::Align::START); - label->set_justify(Gtk::Justification::CENTER); - + set_child(box); + box.add_css_class("user"); + box.set_orientation(Gtk::Orientation::VERTICAL); + image.set_halign(Gtk::Align::CENTER); + image.set_valign(Gtk::Align::END); + label.set_halign(Gtk::Align::CENTER); + label.set_valign(Gtk::Align::START); + label.set_justify(Gtk::Justification::CENTER); std::string username = getlogin(); - - label->set_label(username); + label.set_label(username); if (image_path == "") { - image->hide(); + image.hide(); } else { - image->set(image_path); + image.set(image_path); } + box.append(image); + box.append(label); +} - box->append(*image); - box->append(*label); - grid->attach(*box, position); +void WayfireLockerUserPlugin::add_output(int id, std::shared_ptr grid) +{ + widgets.emplace(id, new WayfireLockerUserPluginWidget(image_path)); + auto widget = widgets[id]; + grid->attach(*widget, position); } void WayfireLockerUserPlugin::remove_output(int id, std::shared_ptr grid) { - grid->remove(*boxes[id]); - labels.erase(id); - images.erase(id); - boxes.erase(id); + grid->remove(*widgets[id]); + widgets.erase(id); } \ No newline at end of file diff --git a/src/locker/plugin/user.hpp b/src/locker/plugin/user.hpp index 74b9834d..dead236a 100644 --- a/src/locker/plugin/user.hpp +++ b/src/locker/plugin/user.hpp @@ -4,6 +4,16 @@ #include "plugin.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" + +class WayfireLockerUserPluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Box box; + Gtk::Image image; + Gtk::Label label; + WayfireLockerUserPluginWidget(std::string image_path); +}; class WayfireLockerUserPlugin : public WayfireLockerPlugin { @@ -14,9 +24,7 @@ class WayfireLockerUserPlugin : public WayfireLockerPlugin void init() override; void deinit() override; - std::map> labels; - std::map> images; - std::map> boxes; + std::map> widgets; std::string image_path = ""; }; diff --git a/src/locker/plugin/volume.cpp b/src/locker/plugin/volume.cpp index 6bcd4fc0..ad507006 100644 --- a/src/locker/plugin/volume.cpp +++ b/src/locker/plugin/volume.cpp @@ -5,6 +5,7 @@ #include "lockergrid.hpp" #include "volume.hpp" #include "plugin.hpp" +#include "timedrevealer.hpp" static void default_sink_changed(GvcMixerControl *gvc_control, guint id, gpointer user_data) @@ -36,49 +37,46 @@ static void notify_source_muted(GvcMixerControl *gvc_control, void WayfireLockerVolumePlugin::update_button_images() { - if (gvc_sink_stream) + for (auto &it : widgets) { - for (auto& it : sink_buttons) + if (gvc_sink_stream) { - it.second->set_icon_name(gvc_mixer_stream_get_is_muted( + it.second->sink_button.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) + if (gvc_source_stream) { - it.second->set_icon_name(gvc_mixer_stream_get_is_muted( + it.second->source_button.set_icon_name(gvc_mixer_stream_get_is_muted( gvc_source_stream) ? "microphone-sensitivity-muted-symbolic" : "microphone-sensitivity-high-symbolic"); } } } WayfireLockerVolumePlugin::WayfireLockerVolumePlugin(): - WayfireLockerPlugin("locker/volume_enable", "locker/volume_position") + WayfireLockerPlugin("locker/volume") { } - -void WayfireLockerVolumePlugin::add_output(int id, std::shared_ptr grid) +WayfireLockerVolumePluginWidget::WayfireLockerVolumePluginWidget(): + WayfireLockerTimedRevealer("locker/volume_always") { - source_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); - sink_buttons.emplace(id, std::shared_ptr(new Gtk::Button())); - inner_boxes.emplace(id, std::shared_ptr(new Gtk::Box)); - auto source_button = source_buttons[id]; - auto sink_button = sink_buttons[id]; + set_child(box); + sink_button.add_css_class("volume-button"); + source_button.add_css_class("mic-button"); - sink_button->add_css_class("volume-button"); - source_button->add_css_class("mic-button"); + box.append(source_button); + box.append(sink_button); +} - auto inner_box = inner_boxes[id]; - inner_box->append(*source_button); - inner_box->append(*sink_button); - grid->attach(*inner_box, position); - sink_button->signal_clicked().connect( +void WayfireLockerVolumePlugin::add_output(int id, std::shared_ptr grid) +{ + widgets.emplace(id, new WayfireLockerVolumePluginWidget()); + auto widget = widgets[id]; + grid->attach(*widget, position); + + widget->sink_button.signal_clicked().connect( [=] () { if (!gvc_sink_stream) @@ -90,7 +88,7 @@ void WayfireLockerVolumePlugin::add_output(int id, std::shared_ptrsignal_clicked().connect( + widget->source_button.signal_clicked().connect( [=] () { if (!gvc_source_stream) @@ -107,9 +105,8 @@ void WayfireLockerVolumePlugin::add_output(int id, std::shared_ptr grid) { - - source_buttons.erase(id); - sink_buttons.erase(id); + grid->remove(*widgets[id]); + widgets.erase(id); } void WayfireLockerVolumePlugin::init() diff --git a/src/locker/plugin/volume.hpp b/src/locker/plugin/volume.hpp index 4c04cfe1..d8091dfd 100644 --- a/src/locker/plugin/volume.hpp +++ b/src/locker/plugin/volume.hpp @@ -8,6 +8,16 @@ #include "gvc-mixer-control.h" #include "plugin.hpp" #include "lockergrid.hpp" +#include "timedrevealer.hpp" + +class WayfireLockerVolumePluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Box box; + Gtk::Button sink_button; + Gtk::Button source_button; + WayfireLockerVolumePluginWidget(); +}; class WayfireLockerVolumePlugin : public WayfireLockerPlugin { @@ -34,7 +44,5 @@ class WayfireLockerVolumePlugin : public WayfireLockerPlugin void on_default_sink_changed(); void on_default_source_changed(); - std::map> inner_boxes; - std::map> sink_buttons; - std::map> source_buttons; + std::map> widgets; }; diff --git a/src/locker/plugin/weather.cpp b/src/locker/plugin/weather.cpp index 77e1ef3e..a30a4a21 100644 --- a/src/locker/plugin/weather.cpp +++ b/src/locker/plugin/weather.cpp @@ -2,11 +2,11 @@ #include #include #include -#include -#include +#include "gtkmm/enums.h" #include "lockergrid.hpp" #include "weather.hpp" +#include "timedrevealer.hpp" #include "wayfire/nonstd/json.hpp" @@ -14,7 +14,7 @@ void WayfireLockerWeatherPlugin::update_labels(std::string text) { for (auto& it : weather_widgets) { - ((Gtk::Label *)it.second->get_first_child())->set_markup(text); + it.second->label.set_markup(text); } label_contents = text; @@ -24,31 +24,34 @@ void WayfireLockerWeatherPlugin::update_icons(std::string path) { for (auto& it : weather_widgets) { - ((Gtk::Image *)it.second->get_first_child()->get_next_sibling())->set(path); + it.second->image.set(path); } icon_path = path; } +WayfireLockerWeatherPluginWidget::WayfireLockerWeatherPluginWidget(std::string contents, std::string icon_path): + WayfireLockerTimedRevealer("locker/weather_always") +{ + set_child(box); + label.add_css_class("weather"); + label.set_markup(contents); + label.set_justify(Gtk::Justification::CENTER); + box.append(label); + + image.add_css_class("weather"); + image.set(icon_path); +} + void WayfireLockerWeatherPlugin::add_output(int id, std::shared_ptr grid) { - weather_widgets.emplace(id, std::shared_ptr(new Gtk::Box())); + weather_widgets.emplace(id, new WayfireLockerWeatherPluginWidget(label_contents, icon_path)); auto weather_widget = weather_widgets[id]; if (!shown) { weather_widget->hide(); } - auto label = Gtk::Label(); - label.add_css_class("weather"); - label.set_markup(label_contents); - label.set_justify(Gtk::Justification::CENTER); - weather_widget->append(label); - - Gtk::Image icon(icon_path); - icon.add_css_class("weather"); - weather_widget->append(icon); - grid->attach(*weather_widget, position); } @@ -103,7 +106,7 @@ void WayfireLockerWeatherPlugin::update_weather() } WayfireLockerWeatherPlugin::WayfireLockerWeatherPlugin(): - WayfireLockerPlugin("locker/weather_enable", "locker/weather_position") + WayfireLockerPlugin("locker/weather") {} void WayfireLockerWeatherPlugin::init() diff --git a/src/locker/plugin/weather.hpp b/src/locker/plugin/weather.hpp index 480e8534..45831ce9 100644 --- a/src/locker/plugin/weather.hpp +++ b/src/locker/plugin/weather.hpp @@ -1,11 +1,23 @@ #pragma once #include +#include +#include #include #include "plugin.hpp" +#include "timedrevealer.hpp" #include "wf-option-wrap.hpp" #include "lockergrid.hpp" +class WayfireLockerWeatherPluginWidget : public WayfireLockerTimedRevealer +{ + public: + Gtk::Box box; + Gtk::Label label; + Gtk::Image image; + WayfireLockerWeatherPluginWidget(std::string contents, std::string icon_path); +}; + class WayfireLockerWeatherPlugin : public WayfireLockerPlugin { public: @@ -23,7 +35,7 @@ class WayfireLockerWeatherPlugin : public WayfireLockerPlugin void hide(); void show(); - std::unordered_map> weather_widgets; + std::unordered_map> weather_widgets; std::string label_contents = ""; std::string icon_path = ""; bool shown; diff --git a/src/locker/timedrevealer.cpp b/src/locker/timedrevealer.cpp new file mode 100644 index 00000000..f94c46eb --- /dev/null +++ b/src/locker/timedrevealer.cpp @@ -0,0 +1,94 @@ +#include +#include "timedrevealer.hpp" +#include "glib.h" + +WayfireLockerTimedRevealer::WayfireLockerTimedRevealer(std::string always_option): + always_show(WfOption{always_option}) +{ + if (hide_timeout > 0 && !always_show) + { + set_reveal_child(false); + } else { + set_transition_duration(0); + set_reveal_child(true); + } + auto hide_callback = [this] () { + + Gtk::RevealerTransitionType type = Gtk::RevealerTransitionType::NONE; + switch (hide_animation){ + + case 1: + type = Gtk::RevealerTransitionType::CROSSFADE; + break; + case 2: + type = Gtk::RevealerTransitionType::SLIDE_DOWN; + break; + case 3: + type = Gtk::RevealerTransitionType::SLIDE_LEFT; + break; + case 4: + type = Gtk::RevealerTransitionType::SLIDE_RIGHT; + break; + case 5: + type = Gtk::RevealerTransitionType::SLIDE_UP; + break; + case 6: + type = Gtk::RevealerTransitionType::SWING_DOWN; + break; + case 7: + type = Gtk::RevealerTransitionType::SWING_LEFT; + break; + case 8: + type = Gtk::RevealerTransitionType::SWING_RIGHT; + break; + case 9: + type = Gtk::RevealerTransitionType::SWING_UP; + break; + default: + type = Gtk::RevealerTransitionType::NONE; + break; + } + set_transition_type(type); + }; + + hide_callback(); + hide_animation.set_callback(hide_callback); + + auto hide_duration_callback = [this] () { + set_transition_duration(hide_animation_duration); + return G_SOURCE_REMOVE; + }; + + + + hide_duration_callback(); + hide_animation_duration.set_callback(hide_duration_callback); +} + +WayfireLockerTimedRevealer::~WayfireLockerTimedRevealer() +{ + if (signal) + { + signal.disconnect(); + } +} + +void WayfireLockerTimedRevealer::activity() +{ + if (signal) + { + signal.disconnect(); + } + set_reveal_child(true); + if (always_show || hide_timeout == 0) + { + return; + } + Glib::signal_timeout().connect( + [this] () { + set_reveal_child(false); + return G_SOURCE_REMOVE; + } + , hide_timeout + ); +} \ No newline at end of file diff --git a/src/locker/timedrevealer.hpp b/src/locker/timedrevealer.hpp new file mode 100644 index 00000000..b916240f --- /dev/null +++ b/src/locker/timedrevealer.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +#include "wf-option-wrap.hpp" +#include + +class WayfireLockerTimedRevealer : public Gtk::Revealer { + private: + sigc::connection signal; + public: + WayfireLockerTimedRevealer(std::string always_option); + ~WayfireLockerTimedRevealer(); + WfOption always_show; + WfOption hide_timeout {"locker/hide_time"}; + WfOption hide_animation { "locker/hide_anim"}; + WfOption hide_animation_duration {"locker/hide_anim_dur"}; + + virtual void activity(); /* Allow plugins to have their own logic if more intricate */ +}; \ No newline at end of file diff --git a/src/util/wf-shell-app.cpp b/src/util/wf-shell-app.cpp index e1265777..e6afd41b 100644 --- a/src/util/wf-shell-app.cpp +++ b/src/util/wf-shell-app.cpp @@ -302,7 +302,7 @@ WayfireShellApp::WayfireShellApp() void WayfireShellApp::init_app() { std::cout << "setting up" << std::endl; - app = Gtk::Application::create(this->get_application_name(), Gio::Application::Flags::HANDLES_COMMAND_LINE | this->get_extra_application_flags()); + app = Gtk::Application::create(this->get_application_name(), Gio::Application::Flags::NONE| this->get_extra_application_flags()); app->signal_activate().connect( sigc::mem_fun(*this, &WayfireShellApp::on_activate)); app->add_main_option_entry( From cee74a0b319148423b305cce4326ac42c6febb4f Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Tue, 27 Jan 2026 16:18:43 -0700 Subject: [PATCH 53/67] weather: Fix icon broken by refactor --- src/locker/plugin/weather.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/locker/plugin/weather.cpp b/src/locker/plugin/weather.cpp index a30a4a21..0a3d963e 100644 --- a/src/locker/plugin/weather.cpp +++ b/src/locker/plugin/weather.cpp @@ -37,10 +37,11 @@ WayfireLockerWeatherPluginWidget::WayfireLockerWeatherPluginWidget(std::string c label.add_css_class("weather"); label.set_markup(contents); label.set_justify(Gtk::Justification::CENTER); - box.append(label); + box.prepend(label); image.add_css_class("weather"); image.set(icon_path); + box.append(image); } void WayfireLockerWeatherPlugin::add_output(int id, std::shared_ptr grid) From 6c8713c92ff9e18c1d317e85cd7134722855a299 Mon Sep 17 00:00:00 2001 From: trigg Date: Thu, 29 Jan 2026 18:34:30 +0000 Subject: [PATCH 54/67] - Fix commas in values 1000 and above - Implemented fingerprint images and styling - Implemented auth fail lockout - Removed PIN submit button - Fixed fade-in, again - Simplified flow of fingerprint reader - Reduced timeouts in fingerprint reader - MPRIS updates play/pause icons depending on state - MPRIS hides self again on stop --- data/css/default.css | 14 +- metadata/locker.xml | 14 +- src/locker/locker.cpp | 54 ++++++-- src/locker/locker.hpp | 10 +- src/locker/lockscreen.cpp | 1 - src/locker/plugin.hpp | 5 +- src/locker/plugin/fingerprint.cpp | 216 +++++++++++++++++------------- src/locker/plugin/fingerprint.hpp | 19 +-- src/locker/plugin/mpris.cpp | 15 ++- src/locker/plugin/pin.cpp | 36 +++-- src/locker/plugin/pin.hpp | 4 +- src/util/css-config.cpp | 7 +- 12 files changed, 258 insertions(+), 137 deletions(-) diff --git a/data/css/default.css b/data/css/default.css index 6233467e..930ba830 100644 --- a/data/css/default.css +++ b/data/css/default.css @@ -145,9 +145,17 @@ animation-iteration-count: 1; animation-fill-mode: forwards; } - -revealer.wf-locker { - border: 2px solid rgba(128,128,128,0.1); +.wf-locker .fingerprint-overlay-image { + -gtk-icon-size: 64px; +} +.wf-locker .fingerprint-overlay-image.good { + color: #0f0; +} +.wf-locker .fingerprint-overlay-image.bad { + color: #f00; +} +.wf-locker .fingerprint-overlay-image.info { + color: #88f; } .wf-locker .mpris image.albumart { -gtk-icon-size:96px; diff --git a/metadata/locker.xml b/metadata/locker.xml index e5ed9a9e..c448cb0a 100644 --- a/metadata/locker.xml +++ b/metadata/locker.xml @@ -9,10 +9,6 @@ <_short>Background Color gtk_headerbar - + + <_short>Password diff --git a/src/locker/locker.cpp b/src/locker/locker.cpp index 9c08c087..8ab73fb0 100644 --- a/src/locker/locker.cpp +++ b/src/locker/locker.cpp @@ -80,18 +80,19 @@ void WayfireLockerApp::on_activate() { if (can_early_wake) { - Glib::signal_timeout().connect_seconds([this](){ + prewake_signal = Glib::signal_timeout().connect([this](){ can_early_wake = false; return G_SOURCE_REMOVE; }, WfOption {"locker/prewake"}); } perform_lock(); } + /* Called again but already screen locked. No worries */ return; } /* Set a timer for early-wake unlock */ WayfireShellApp::on_activate(); - Glib::signal_timeout().connect([this](){ + prewake_signal = Glib::signal_timeout().connect([this](){ can_early_wake = false; return G_SOURCE_REMOVE; }, WfOption {"locker/prewake"}); @@ -220,7 +221,6 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) it.second->add_output(id, window->grid); } } - window->signal_close_request().connect([this, id] () { for (auto& it : plugins) @@ -252,6 +252,10 @@ void WayfireLockerApp::on_monitor_present(GdkMonitor *monitor) { gtk_session_lock_instance_assign_window_to_monitor(lock, window->gobj(), monitor); } + if (can_early_wake) + { + window->add_css_class("fade-in"); + } } /* Called on any successful auth to unlock & end locker */ @@ -276,10 +280,18 @@ void WayfireLockerApp::perform_unlock(std::string reason) { gtk_session_lock_instance_unlock(lock); } - for(auto &it : window_list) + for (auto &it : window_list) { it.second->disconnect(); } + if (lockout_signal) + { + lockout_signal.disconnect(); + } + if (prewake_signal) + { + prewake_signal.disconnect(); + } return G_SOURCE_REMOVE; }); } @@ -308,10 +320,6 @@ bool WayfireLockerApp::is_locked() void WayfireLockerApp::set_is_locked(bool locked) { m_is_locked = locked; - if (!locked) - { - can_early_wake = true; // Reset state Before next activate - } } /* Starting point */ @@ -408,4 +416,34 @@ void WayfireLockerApp::user_activity() can_early_wake = false; perform_unlock("Early Activity"); } +} + +void WayfireLockerApp::recieved_bad_auth() +{ + bad_auth_count ++; + if (bad_auth_count > WfOption{"locker/lockout_attempts"}) + { + // Lockout now + lockout = true; + for (auto &it : plugins) + { + it.second->lockout_changed(true); + } + // + lockout_signal = Glib::signal_timeout().connect_seconds( + [this] () { + lockout = false; + bad_auth_count = 0; + for (auto &it : plugins) + { + it.second->lockout_changed(false); + } + return G_SOURCE_REMOVE; + }, WfOption{"locker/lockout_timer"}); + } +} + +bool WayfireLockerApp::is_locked_out() +{ + return lockout; } \ No newline at end of file diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index d9498734..d18e831a 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -30,8 +30,11 @@ class WayfireLockerApp : public WayfireShellApp bool m_is_locked = false; bool instant_lock = false; int window_id_count = 0; - + int bad_auth_count = 0; + bool lockout = false; + std::vector> css_rules; + sigc::connection lockout_signal, prewake_signal; public: using WayfireShellApp::WayfireShellApp; static void create(int argc, char **argv); @@ -67,8 +70,11 @@ class WayfireLockerApp : public WayfireShellApp void perform_lock(); void init_plugins(); void deinit_plugins(); - bool can_early_wake; + bool can_early_wake = true; void user_activity(); + void recieved_bad_auth(); + bool is_locked_out(); + std::map> window_list; }; diff --git a/src/locker/lockscreen.cpp b/src/locker/lockscreen.cpp index c654e353..f40328e4 100644 --- a/src/locker/lockscreen.cpp +++ b/src/locker/lockscreen.cpp @@ -7,7 +7,6 @@ WayfireLockerAppLockscreen::WayfireLockerAppLockscreen() grid = std::shared_ptr(new WayfireLockerGrid()); set_child(*grid); add_css_class("wf-locker"); - add_css_class("fade-in"); grid->set_expand(true); /* Mouse press or screen touch */ diff --git a/src/locker/plugin.hpp b/src/locker/plugin.hpp index 61e0e44b..18013049 100644 --- a/src/locker/plugin.hpp +++ b/src/locker/plugin.hpp @@ -22,7 +22,8 @@ class WayfireLockerPlugin WfOption position; virtual void add_output(int id, std::shared_ptr grid) = 0; virtual void remove_output(int id, std::shared_ptr grid) = 0; - virtual void init() = 0; - virtual void deinit() = 0; + virtual void init() = 0; /* Called just before lockscreens shown. */ + virtual void deinit() = 0; /* Called after lockscreen unlocked. */ + virtual void lockout_changed(bool lockout){}; /* Called when too many failed logins have occured */ virtual ~WayfireLockerPlugin() = default; }; diff --git a/src/locker/plugin/fingerprint.cpp b/src/locker/plugin/fingerprint.cpp index 7de1443e..9cde5313 100644 --- a/src/locker/plugin/fingerprint.cpp +++ b/src/locker/plugin/fingerprint.cpp @@ -79,34 +79,43 @@ void WayfireLockerFingerprintPlugin::get_device() void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtr & result) { device_proxy = Gio::DBus::Proxy::create_finish(result); - update_labels("Listing fingers..."); + update("Listing fingers...", "system-search-symbolic", "info"); char *username = getlogin(); auto reply = device_proxy->call_sync("ListEnrolledFingers", nullptr, Glib::Variant>::create(username)); Glib::Variant> array; reply.get_child(array, 0); - if (array.get_n_children() > 0) - { - // User has at least one fingerprint on file! - show(); - update_labels("Fingerprint Ready"); - update_image("fingerprint"); - } else + if (array.get_n_children() == 0) { // Zero fingers for this user. show(); - update_labels("No fingerprints enrolled"); - update_image("nofingerprint"); + update("No fingerprints enrolled", "dialog-error-symbolic", "bad"); // Don't hide entirely, allow the user to see this specific fail return; } - + show(); + update("Fingerprint Device Ready", "system-search-symbolic", "info"); Glib::Variant finger; reply.get_child(finger, 0); - update_labels("Finger print device found"); - /* Attach a listener now, useful when we start scanning */ + start_fingerprint_scanning(); +} + +void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() +{ + if (!enable) + { + return; + } + if (WayfireLockerApp::get().is_locked_out()) + { + return; + } + if (signal) + { + signal.disconnect(); + } signal = device_proxy->signal_signal().connect([this] (const Glib::ustring & sender_name, const Glib::ustring & signal_name, const Glib::VariantContainerBase & params) @@ -123,36 +132,45 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrstart_fingerprint_scanning(); return G_SOURCE_REMOVE; - }, 5); - show(); - update_image("nofingerprint"); - update_labels("Invalid fingerprint"); + }, 500); + return; } else if (mesg.get() == "verify-unknown-error") { - is_done = true; + update("Unknown error", "dialog-error-symbolic", "info"); + stop_fingerprint_scanning(); /* Reschedule fingerprint scan */ - Glib::signal_timeout().connect_seconds( + starting_fingerprint = Glib::signal_timeout().connect( [this] () { this->start_fingerprint_scanning(); return G_SOURCE_REMOVE; - }, 5); + }, 500); + return; } else if (mesg.get() == "verify-disconnected") { + update("Reader disconnected", "dialog-error-symbolic", "bad"); /* This needs testing on a machine with removable fprint reader */ device_proxy = nullptr; if (signal) @@ -160,7 +178,7 @@ void WayfireLockerFingerprintPlugin::on_device_acquired(const Glib::RefPtrcall_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" << std::endl; - update_labels("Fingerprint reader busy..."); - Glib::signal_timeout().connect_seconds( - [this] () - { - this->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 */ -} - -void WayfireLockerFingerprintPlugin::release_device() -{ - if (device_proxy) - { - device_proxy->call_sync("Release"); - } -} - -void WayfireLockerFingerprintPlugin::start_fingerprint_scanning() -{ - if (!enable) - { - return; - } if (device_proxy) { + if (starting_fingerprint) + { + starting_fingerprint.disconnect(); + } + try { + char *username = getlogin(); + device_proxy->call_sync("Claim", nullptr, + Glib::Variant>::create({username})); + } catch (Glib::Error & e) /* TODO : Narrow down? */ + { + stop_fingerprint_scanning(); + std::cout << "Fingerprint device already claimed, try in 3s" << std::endl; + update("Fingerprint reader busy...", "dialog-error-symbolic", "info"); + Glib::signal_timeout().connect_seconds( + [this] () + { + this->start_fingerprint_scanning(); + return G_SOURCE_REMOVE; + }, 3); + return; + } show(); - update_labels("Use fingerprint to unlock"); + update("Use fingerprint to unlock", "process-completed-symbolic", "good"); device_proxy->call_sync("VerifyStart", nullptr, Glib::Variant>::create({""})); } else { - update_labels("Unable to start fingerprint scan"); + update("Unable to start fingerprint scan", "dialog-error-symbolic", "bad"); + hide(); } } @@ -251,10 +244,15 @@ void WayfireLockerFingerprintPlugin::stop_fingerprint_scanning() { return; } + if(signal) + { + signal.disconnect(); + } /* Stop if running. Eventually log or respond to errors but for now, avoid crashing lockscreen on close-down */ try{ device_proxy->call_sync("VerifyStop"); + device_proxy->call_sync("Release"); } catch(Glib::Error & e) { @@ -300,31 +298,66 @@ void WayfireLockerFingerprintPlugin::deinit() { // Ensure we return state to allow other programs to use scanner stop_fingerprint_scanning(); - release_device(); - if(signal) + if (signal) { signal.disconnect(); } + if (starting_fingerprint) + { + starting_fingerprint.disconnect(); + } + if (finding_new_device) + { + finding_new_device.disconnect(); + } device_proxy = nullptr; } -WayfireLockerFingerprintPluginWidget::WayfireLockerFingerprintPluginWidget(std::string label_contents, std::string image_contents): +WayfireLockerFingerprintPluginWidget::WayfireLockerFingerprintPluginWidget(std::string label_contents, std::string image_contents, std::string color_contents): WayfireLockerTimedRevealer("locker/fingerprint_always") { set_child(box); - image.set_from_icon_name(image_contents); + image_print.set_from_icon_name("auth-fingerprint-symbolic"); + image_overlay.set_from_icon_name(image_contents); label.set_label(label_contents); + overlay.set_child(image_print); + overlay.add_overlay(image_overlay); + image_overlay.set_halign(Gtk::Align::END); + image_overlay.set_valign(Gtk::Align::END); - image.add_css_class("fingerprint-icon"); + overlay.add_css_class("fingerprint-overlay"); + image_print.add_css_class("fingerprint-icon"); + image_overlay.add_css_class("fingerprint-overlay-image"); label.add_css_class("fingerprint-text"); + if(color_contents != "") + { + image_overlay.add_css_class(color_contents); + } + box.set_orientation(Gtk::Orientation::VERTICAL); - box.append(image); + box.append(overlay); box.append(label); } +void WayfireLockerFingerprintPlugin::lockout_changed(bool lockout) +{ + if (lockout) + { + update("Too many attempts", "dialog-error-symbolic", "bad"); + stop_fingerprint_scanning(); + } else + { + if (enable && device_proxy) + { + show(); + start_fingerprint_scanning(); + } + } +} + void WayfireLockerFingerprintPlugin::add_output(int id, std::shared_ptr grid) { - widgets.emplace(id, new WayfireLockerFingerprintPluginWidget(label_contents, icon_contents)); + widgets.emplace(id, new WayfireLockerFingerprintPluginWidget(label_contents, icon_contents, color_contents)); auto widget = widgets[id]; if (!show_state) { @@ -339,24 +372,23 @@ void WayfireLockerFingerprintPlugin::remove_output(int id, std::shared_ptrimage.set_from_icon_name(image); - } - icon_contents = image; -} + label_contents = label; + color_contents = color; -void WayfireLockerFingerprintPlugin::update_labels(std::string text) -{ for (auto& it : widgets) { - it.second->label.set_label(text); + it.second->label.set_label(label); + auto widget = &it.second->image_overlay; + widget->set_from_icon_name(image); + widget->remove_css_class("info"); + widget->remove_css_class("bad"); + widget->remove_css_class("good"); + widget->add_css_class(color); } - label_contents = text; } void WayfireLockerFingerprintPlugin::hide() @@ -375,4 +407,4 @@ void WayfireLockerFingerprintPlugin::show() { it.second->show(); } -} +} \ No newline at end of file diff --git a/src/locker/plugin/fingerprint.hpp b/src/locker/plugin/fingerprint.hpp index 68c7309f..3a67a0da 100644 --- a/src/locker/plugin/fingerprint.hpp +++ b/src/locker/plugin/fingerprint.hpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -18,9 +19,11 @@ class WayfireLockerFingerprintPluginWidget : public WayfireLockerTimedRevealer { public: Gtk::Box box; - Gtk::Image image; + Gtk::Overlay overlay; + Gtk::Image image_print; + Gtk::Image image_overlay; Gtk::Label label; - WayfireLockerFingerprintPluginWidget(std::string label_contents, std::string image_contents); + WayfireLockerFingerprintPluginWidget(std::string label_contents, std::string image_contents, std::string color_contents); }; class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin @@ -28,6 +31,8 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin private: DBusConnection connection; Glib::RefPtr device_proxy, manager_proxy; + sigc::connection signal; + sigc::connection starting_fingerprint, finding_new_device; public: WayfireLockerFingerprintPlugin(); @@ -35,24 +40,22 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin void on_connection(const Glib::RefPtr & connection, const Glib::ustring & name); void get_device(); void on_device_acquired(const Glib::RefPtr & result); - void claim_device(); - void release_device(); void start_fingerprint_scanning(); void stop_fingerprint_scanning(); void add_output(int id, std::shared_ptr grid) override; void remove_output(int id, std::shared_ptr grid) override; void init() override; void deinit() override; + void lockout_changed(bool lockout) override; void hide(); void show(); + void color(std::string color); - sigc::connection signal; - sigc::connection starting_fingerprint; bool show_state = false; - void update_labels(std::string text); - void update_image(std::string image); + void update(std::string text, std::string image, std::string color); std::map> widgets; std::string icon_contents = ""; std::string label_contents = ""; + std::string color_contents = ""; }; diff --git a/src/locker/plugin/mpris.cpp b/src/locker/plugin/mpris.cpp index 1ae573d6..4279a04a 100644 --- a/src/locker/plugin/mpris.cpp +++ b/src/locker/plugin/mpris.cpp @@ -120,7 +120,7 @@ WayfireLockerMPRISWidget::WayfireLockerMPRISWidget(std::string name, proxy->get_cached_property(cancontrol_value, "CanControl"); cancontrol(cancontrol_value.get()); - kill.set_icon_name("close"); + kill.set_icon_name("media-playback-stop"); playpause.set_icon_name("media-playback-pause"); prev.set_icon_name("media-skip-backward"); next.set_icon_name("media-skip-forward"); @@ -138,6 +138,19 @@ WayfireLockerMPRISWidget::~WayfireLockerMPRISWidget() void WayfireLockerMPRISWidget::playbackstatus(std::string value) { + if (value == "Stopped") + { + box.hide(); + return; + } + box.show(); + if (value == "Paused") + { + playpause.set_icon_name("media-playback-start"); + } else + { + playpause.set_icon_name("media-playback-pause"); + } activity(); } diff --git a/src/locker/plugin/pin.cpp b/src/locker/plugin/pin.cpp index 9a129786..a8a6440a 100644 --- a/src/locker/plugin/pin.cpp +++ b/src/locker/plugin/pin.cpp @@ -44,10 +44,7 @@ WayfireLockerPinPluginWidget::WayfireLockerPinPluginWidget(): }); } - 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( @@ -57,13 +54,6 @@ WayfireLockerPinPluginWidget::WayfireLockerPinPluginWidget(): 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"); } @@ -84,7 +74,6 @@ void WayfireLockerPinPluginWidget::init(std::string label_text) grid.attach(numbers[7], 0, 3); grid.attach(numbers[8], 1, 3); grid.attach(numbers[9], 2, 3); - grid.attach(bsub, 2, 4); grid.attach(numbers[0], 1, 4); grid.attach(bcan, 0, 4); grid.set_vexpand(true); @@ -171,10 +160,16 @@ void WayfireLockerPinPlugin::add_digit(std::string digit) { pin = pin + digit; update_labels(); + + submit_pin(); } void WayfireLockerPinPlugin::reset_pin() { + if (pin.length() > 0) + { + WayfireLockerApp::get().recieved_bad_auth(); + } pin = ""; update_labels(); } @@ -195,8 +190,6 @@ void WayfireLockerPinPlugin::submit_pin() { WayfireLockerApp::get().perform_unlock("PIN Authenticated"); } - - pin = ""; update_labels(); } @@ -219,3 +212,20 @@ std::string WayfireLockerPinPlugin::sha512(const std::string input) return ss.str(); } + +void WayfireLockerPinPluginWidget::lockout_changed(bool lockout) +{ + for (int i = 0; i < 10; i ++) + { + numbers[i].set_sensitive(!lockout); + } + bcan.set_sensitive(!lockout); +} + +void WayfireLockerPinPlugin::lockout_changed(bool lockout) +{ + for (auto &it : pinpads) + { + it.second->lockout_changed(lockout); + } +} \ No newline at end of file diff --git a/src/locker/plugin/pin.hpp b/src/locker/plugin/pin.hpp index 6d0699f3..5b2bb4c8 100644 --- a/src/locker/plugin/pin.hpp +++ b/src/locker/plugin/pin.hpp @@ -14,8 +14,9 @@ class WayfireLockerPinPluginWidget : public WayfireLockerTimedRevealer public: WayfireLockerPinPluginWidget(); ~WayfireLockerPinPluginWidget(); + void lockout_changed(bool lockout); Gtk::Grid grid; - Gtk::Button bsub, bcan; + Gtk::Button bcan; Gtk::Label label; void init(std::string label); void check(); @@ -30,6 +31,7 @@ class WayfireLockerPinPlugin : public WayfireLockerPlugin void remove_output(int id, std::shared_ptr grid) override; void init() override; void deinit() override; + void lockout_changed(bool lockout) override; bool disabled = false; void update_labels(); diff --git a/src/util/css-config.cpp b/src/util/css-config.cpp index 5468cf23..111baafd 100644 --- a/src/util/css-config.cpp +++ b/src/util/css-config.cpp @@ -2,6 +2,7 @@ #include #include #include +#include void CssFromConfig::add_provider() { @@ -32,13 +33,15 @@ CssFromConfigInt::CssFromConfigInt(std::string option_name, std::string css_befo provider = Gtk::CssProvider::create(); option_value.set_callback([=] { + int value = option_value; // TODO When we go up to c++20 use std::format std::stringstream ss; - ss << css_before << option_value << css_after; + ss << css_before << std::to_string(value) << css_after; provider->load_from_string(ss.str()); }); + int value = option_value; std::stringstream ss; - ss << css_before << option_value << css_after; + ss << css_before << std::to_string(value) << css_after; provider->load_from_string(ss.str()); add_provider(); From aac88fe0a121960d7206aa0da8f891ae4b543cbe Mon Sep 17 00:00:00 2001 From: trigg Date: Fri, 30 Jan 2026 21:33:23 +0000 Subject: [PATCH 55/67] - Split BackgroundGL out as a widget of its own - wf-background writes to user temporary cache when background image changes - locker picks up background image changes and matches - recrustify - wf-background inhibit output is now a user option --- metadata/background.xml.in | 4 + metadata/locker.xml | 4 + src/background/background.cpp | 657 ++++++---------------------------- src/background/background.hpp | 111 ++---- src/locker/locker.cpp | 57 ++- src/locker/locker.hpp | 20 +- src/locker/lockscreen.cpp | 30 +- src/locker/lockscreen.hpp | 7 +- src/locker/meson.build | 1 + src/util/background-gl.cpp | 402 +++++++++++++++++++++ src/util/background-gl.hpp | 54 +++ src/util/meson.build | 1 + 12 files changed, 700 insertions(+), 648 deletions(-) create mode 100644 src/util/background-gl.cpp create mode 100644 src/util/background-gl.hpp diff --git a/metadata/background.xml.in b/metadata/background.xml.in index be3f88e8..cdf9e6ce 100644 --- a/metadata/background.xml.in +++ b/metadata/background.xml.in @@ -21,6 +21,10 @@ <_short>Randomize false +