diff --git a/metadata/meson.build b/metadata/meson.build
index 3a8b5ab62..905c2cf4f 100644
--- a/metadata/meson.build
+++ b/metadata/meson.build
@@ -42,3 +42,4 @@ install_data('shortcuts-inhibit.xml', install_dir: conf_data.get('PLUGIN_XML_DIR
install_data('wsets.xml', install_dir: conf_data.get('PLUGIN_XML_DIR'))
install_data('wayfire-shell.xml', install_dir: conf_data.get('PLUGIN_XML_DIR'))
install_data('xdg-activation.xml', install_dir: conf_data.get('PLUGIN_XML_DIR'))
+install_data('session-lock.xml', install_dir: conf_data.get('PLUGIN_XML_DIR'))
diff --git a/metadata/session-lock.xml b/metadata/session-lock.xml
new file mode 100644
index 000000000..ad1fef193
--- /dev/null
+++ b/metadata/session-lock.xml
@@ -0,0 +1,8 @@
+
+
+
+ <_short>Session Lock Protocol
+ <_long>An implementation of the ext-session-lock-v1 protocol. Provides more secure screen locking.
+ Utility
+
+
diff --git a/plugins/common/wayfire/plugins/common/simple-text-node.hpp b/plugins/common/wayfire/plugins/common/simple-text-node.hpp
new file mode 100644
index 000000000..f0d801c1c
--- /dev/null
+++ b/plugins/common/wayfire/plugins/common/simple-text-node.hpp
@@ -0,0 +1,72 @@
+#include "wayfire/opengl.hpp"
+#include "wayfire/output.hpp"
+#include "wayfire/scene.hpp"
+#include
+
+class simple_text_node_t : public wf::scene::node_t
+{
+ class render_instance_t : public wf::scene::simple_render_instance_t
+ {
+ public:
+ using simple_render_instance_t::simple_render_instance_t;
+
+ void render(const wf::render_target_t& target, const wf::region_t& region)
+ {
+ OpenGL::render_begin(target);
+
+ auto g = self->get_bounding_box();
+ for (auto box : region)
+ {
+ target.logic_scissor(wlr_box_from_pixman_box(box));
+ OpenGL::render_texture(self->cr_text.tex.tex, target, g, glm::vec4(1.0f),
+ OpenGL::TEXTURE_TRANSFORM_INVERT_Y);
+ }
+
+ OpenGL::render_end();
+ }
+ };
+
+ wf::cairo_text_t cr_text;
+
+ public:
+ simple_text_node_t() : node_t(false)
+ {}
+
+ void gen_render_instances(std::vector& instances,
+ wf::scene::damage_callback push_damage, wf::output_t *output) override
+ {
+ instances.push_back(std::make_unique(this, push_damage, output));
+ }
+
+ wf::geometry_t get_bounding_box() override
+ {
+ return wf::construct_box(position, size.value_or(cr_text.get_size()));
+ }
+
+ void set_position(wf::point_t position)
+ {
+ this->position = position;
+ }
+
+ void set_size(wf::dimensions_t size)
+ {
+ this->size = size;
+ }
+
+ void set_text_params(wf::cairo_text_t::params params)
+ {
+ this->params = params;
+ }
+
+ void set_text(std::string text)
+ {
+ wf::scene::damage_node(this->shared_from_this(), get_bounding_box());
+ cr_text.render_text(text, params);
+ wf::scene::damage_node(this->shared_from_this(), get_bounding_box());
+ }
+
+ private:
+ wf::cairo_text_t::params params;
+ std::optional size;
+ wf::point_t position;
+};
diff --git a/plugins/protocols/meson.build b/plugins/protocols/meson.build
index a9e951bae..6e2e8e283 100644
--- a/plugins/protocols/meson.build
+++ b/plugins/protocols/meson.build
@@ -1,9 +1,10 @@
protocol_plugins = [
- 'foreign-toplevel', 'gtk-shell', 'wayfire-shell', 'xdg-activation', 'shortcuts-inhibit', 'input-method-v1'
+ 'foreign-toplevel', 'gtk-shell', 'wayfire-shell', 'xdg-activation', 'shortcuts-inhibit',
+ 'input-method-v1', 'session-lock'
]
all_include_dirs = [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc]
-all_deps = [wlroots, pixman, wfconfig, wf_protos, json]
+all_deps = [wlroots, pixman, wfconfig, wf_protos, json, cairo, pango]
foreach plugin : protocol_plugins
shared_module(plugin, plugin + '.cpp',
diff --git a/plugins/protocols/session-lock.cpp b/plugins/protocols/session-lock.cpp
new file mode 100644
index 000000000..7ce13343b
--- /dev/null
+++ b/plugins/protocols/session-lock.cpp
@@ -0,0 +1,426 @@
+#include "wayfire/core.hpp"
+
+#include "wayfire/seat.hpp"
+#include "wayfire/scene-input.hpp"
+#include "wayfire/scene-operations.hpp"
+#include "wayfire/unstable/wlr-surface-node.hpp"
+#include "wayfire/unstable/wlr-surface-controller.hpp"
+#include "wayfire/output.hpp"
+#include "wayfire/output-layout.hpp"
+#include "wayfire/signal-definitions.hpp"
+
+#include
+#include
+#include
+#include
+#include
+
+enum lock_state
+{
+ LOCKING,
+ LOCKED,
+ UNLOCKED,
+ DESTROYED,
+ ZOMBIE,
+} state;
+
+class wf_session_lock_plugin : public wf::plugin_interface_t
+{
+ class wayfire_session_lock;
+
+ class lock_surface_node : public wf::scene::wlr_surface_node_t
+ {
+ public:
+ lock_surface_node(wayfire_session_lock *lock,
+ wlr_session_lock_surface_v1 *lock_surface,
+ wf::output_t *output) :
+ wf::scene::wlr_surface_node_t(lock_surface->surface, true /* autocommit */),
+ lock(lock),
+ lock_surface(lock_surface),
+ output(output),
+ interaction(std::make_unique(lock_surface->surface,
+ lock_surface->output))
+ {
+ lock_surface_destroy.set_callback([this] (void *data)
+ {
+ wf::wlr_surface_controller_t::try_free_controller(this->lock_surface->surface);
+ wf::scene::remove_child(shared_from_this());
+ lock_surface_destroy.disconnect();
+ this->lock->surface_destroyed(this->output);
+ const char *name = this->output->handle ? this->output->handle->name : "(deleted)";
+ this->interaction = std::make_unique();
+ LOGC(LSHELL, "lock_surface on ", name, " destroyed");
+ });
+ lock_surface_destroy.connect(&lock_surface->events.destroy);
+ }
+
+ void attach_to_layer()
+ {
+ auto layer_node = output->node_for_layer(wf::scene::layer::LOCK);
+ wf::scene::add_front(layer_node, shared_from_this());
+ wf::wlr_surface_controller_t::create_controller(lock_surface->surface, layer_node);
+ wf::get_core().seat->set_active_node(shared_from_this());
+ wf::get_core().seat->refocus();
+ }
+
+ wf::keyboard_focus_node_t keyboard_refocus(wf::output_t *output) override
+ {
+ if (output != this->output)
+ {
+ return wf::keyboard_focus_node_t{};
+ }
+
+ wf::keyboard_focus_node_t node = {
+ .node = this,
+ .importance = wf::focus_importance::HIGH,
+ .allow_focus_below = false,
+ };
+ return node;
+ }
+
+ class lock_surface_keyboard_interaction : public wf::keyboard_interaction_t
+ {
+ public:
+ lock_surface_keyboard_interaction(wlr_surface *surface, wlr_output *output) :
+ surface(surface), output(output)
+ {}
+
+ void handle_keyboard_enter(wf::seat_t *seat)
+ {
+ wlr_seat_keyboard_enter(seat->seat, surface, nullptr, 0, nullptr);
+ }
+
+ void handle_keyboard_leave(wf::seat_t *seat)
+ {
+ wlr_seat_keyboard_clear_focus(seat->seat);
+ }
+
+ void handle_keyboard_key(wf::seat_t *seat, wlr_keyboard_key_event event)
+ {
+ wlr_seat_keyboard_notify_key(seat->seat, event.time_msec, event.keycode, event.state);
+ }
+
+ private:
+ wlr_surface *surface;
+ wlr_output *output;
+ };
+
+ wf::keyboard_interaction_t& keyboard_interaction()
+ {
+ return *interaction;
+ }
+
+ private:
+ wayfire_session_lock *lock;
+ wlr_session_lock_surface_v1 *lock_surface;
+ wf::output_t *output;
+ std::unique_ptr interaction;
+ wf::wl_listener_wrapper lock_surface_destroy;
+ };
+
+ class backup_node : public simple_text_node_t
+ {
+ public:
+ backup_node(wf::output_t *output) : simple_text_node_t()
+ {
+ set_position({0, 0});
+ // TODO: it seems better to create the node and add it to the back of the scenegraph so
+ // it will be displayed if the client crashes and its surface is destroyed.
+ // Unfortunately this causes the surface to briefly appear before the lock screen.
+ // So make the background completely transparent instead, and then add the text
+ // when the client suraface is destroyed.
+ wf::cairo_text_t::params params(
+ 1280 /* font_size */,
+ wf::color_t{0.1, 0.1, 0.1, 0} /* bg_color */,
+ wf::color_t{0.9, 0.9, 0.9, 1} /* fg_color */);
+ params.rounded_rect = false;
+ set_text_params(params);
+ set_size(output->get_screen_size());
+ }
+
+ void display()
+ {
+ wf::cairo_text_t::params params(
+ 1280 /* font_size */,
+ wf::color_t{0, 0, 0, 1} /* bg_color */,
+ wf::color_t{0.9, 0.9, 0.9, 1} /* fg_color */);
+ set_text_params(params);
+ // TODO: make the text smaller and display a useful message instead of a big explosion.
+ set_text("💥");
+ }
+ };
+
+ struct output_state
+ {
+ output_state(wf::output_t *output) : output(output)
+ {}
+
+ wf::output_t *output;
+ std::shared_ptr surface;
+ std::shared_ptr backup_surface;
+ };
+
+ class wayfire_session_lock
+ {
+ public:
+ wayfire_session_lock(wf_session_lock_plugin *plugin, wlr_session_lock_v1 *lock) :
+ plugin(plugin), lock(lock)
+ {
+ auto& ol = wf::get_core().output_layout;
+ output_added.set_callback([this] (wf::output_added_signal *ev)
+ {
+ handle_output_added(ev->output);
+ });
+ ol->connect(&output_added);
+
+ output_removed.set_callback([this] (wf::output_removed_signal *ev)
+ {
+ handle_output_removed(ev->output);
+ });
+ ol->connect(&output_removed);
+
+ for (auto output : ol->get_outputs())
+ {
+ handle_output_added(output);
+ }
+
+ new_surface.set_callback([this] (void *data)
+ {
+ wlr_session_lock_surface_v1 *lock_surface = (wlr_session_lock_surface_v1*)data;
+ wlr_output *wo = lock_surface->output;
+
+ auto output = wf::get_core().output_layout->find_output(lock_surface->output);
+ if (!output || (output_states.find(output) == output_states.end()))
+ {
+ LOGE("lock_surface created on deleted output ", wo->name);
+ return;
+ }
+
+ auto size = output->get_screen_size();
+ wlr_session_lock_surface_v1_configure(lock_surface, size.width, size.height);
+ LOGC(LSHELL, "surface_configure on ", wo->name, " ", size.width, "x", size.height);
+
+ // TODO: hook into output size changes and reconfigure.
+
+ output_states[output]->surface = std::make_shared(
+ this, lock_surface, output);
+
+ if (state == LOCKED)
+ {
+ // Output is already inhibited.
+ output_states[output]->surface->attach_to_layer();
+ } else if (have_all_surfaces())
+ {
+ // All lock surfaces ready. Lock.
+ lock_timer.disconnect();
+ lock_all();
+ }
+ });
+ new_surface.connect(&lock->events.new_surface);
+
+ unlock.set_callback([this] (void *data)
+ {
+ unlock_all();
+ });
+ unlock.connect(&lock->events.unlock);
+
+ destroy.set_callback([this] (void *data)
+ {
+ output_added.disconnect();
+ output_removed.disconnect();
+ new_surface.disconnect();
+ unlock.disconnect();
+ destroy.disconnect();
+ set_state(state == UNLOCKED ? DESTROYED : ZOMBIE);
+ LOGC(LSHELL, "session lock destroyed");
+ });
+ destroy.connect(&lock->events.destroy);
+
+ lock_timer.set_timeout(1000, [this] (void)
+ {
+ lock_all();
+ });
+ }
+
+ void surface_destroyed(wf::output_t *output)
+ {
+ if (output_states.find(output) != output_states.end())
+ {
+ output_states[output]->surface.reset();
+ if (output_states[output]->backup_surface)
+ {
+ output_states[output]->backup_surface->display();
+ }
+ }
+ }
+
+ ~wayfire_session_lock()
+ {
+ remove_backup_surfaces();
+ }
+
+ private:
+ void handle_output_added(wf::output_t *output)
+ {
+ output_states[output] = std::make_shared(output);
+ if (state == LOCKED)
+ {
+ lock_output(output, output_states[output]);
+ }
+ }
+
+ void handle_output_removed(wf::output_t *output)
+ {
+ output_states.erase(output);
+ }
+
+ bool have_all_surfaces()
+ {
+ for (const auto& [_, output_state] : output_states)
+ {
+ if (output_state->surface == nullptr)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ void lock_output(wf::output_t *output, std::shared_ptr output_state)
+ {
+ output->set_inhibited(true);
+ if (output_state->surface != nullptr)
+ {
+ output_state->surface->attach_to_layer();
+ }
+
+ output_state->backup_surface = std::make_shared(output);
+ output_state->backup_surface->set_text("");
+ auto layer_node = output->node_for_layer(wf::scene::layer::LOCK);
+ wf::scene::add_back(layer_node, output_state->backup_surface);
+ }
+
+ void lock_all()
+ {
+ for (const auto& [output, output_state] : output_states)
+ {
+ lock_output(output, output_state);
+ }
+
+ wlr_session_lock_v1_send_locked(lock);
+ set_state(LOCKED);
+ }
+
+ void remove_backup_surfaces()
+ {
+ for (const auto& [output, output_state] : output_states)
+ {
+ if (output_state->backup_surface)
+ {
+ wf::scene::remove_child(output_state->backup_surface);
+ output_state->backup_surface.reset();
+ }
+ }
+ }
+
+ void unlock_all()
+ {
+ remove_backup_surfaces();
+ for (const auto& [output, output_state] : output_states)
+ {
+ output->set_inhibited(false);
+ }
+
+ set_state(UNLOCKED);
+ LOGC(LSHELL, "unlock");
+ }
+
+ void set_state(lock_state new_state)
+ {
+ state = new_state;
+ plugin->notify_lock_state(state);
+ }
+
+ wf_session_lock_plugin *plugin;
+ wlr_session_lock_v1 *lock;
+ wf::wl_timer lock_timer;
+ std::map> output_states;
+
+ wf::wl_listener_wrapper new_surface;
+ wf::wl_listener_wrapper unlock;
+ wf::wl_listener_wrapper destroy;
+
+ wf::signal::connection_t output_added;
+ wf::signal::connection_t output_removed;
+ };
+
+ public:
+ void init() override
+ {
+ auto display = wf::get_core().display;
+ manager = wlr_session_lock_manager_v1_create(display);
+
+ new_lock.set_callback([this] (void *data)
+ {
+ wlr_session_lock_v1 *wlr_lock = (wlr_session_lock_v1*)data;
+
+ if (cur_lock.get() == nullptr)
+ {
+ cur_lock.reset(new wayfire_session_lock(this, wlr_lock));
+ LOGC(LSHELL, "new_lock");
+ } else
+ {
+ LOGE("new_lock: already locked");
+ wlr_session_lock_v1_destroy(wlr_lock);
+ }
+ });
+ new_lock.connect(&manager->events.new_lock);
+
+ destroy.set_callback([this] (void *data)
+ {
+ LOGC(LSHELL, "session_lock_manager destroyed");
+ });
+ destroy.connect(&manager->events.destroy);
+ }
+
+ void notify_lock_state(lock_state state)
+ {
+ switch (state)
+ {
+ case UNLOCKED:
+ prev_lock.reset();
+ break;
+
+ case DESTROYED:
+ cur_lock.reset();
+ break;
+
+ case ZOMBIE:
+ prev_lock = std::move(cur_lock);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ void fini() override
+ {
+ // TODO: unlock everything?
+ }
+
+ bool is_unloadable() override
+ {
+ return false;
+ }
+
+ private:
+ wlr_session_lock_manager_v1 *manager;
+ wf::wl_listener_wrapper new_lock;
+ wf::wl_listener_wrapper destroy;
+
+ std::shared_ptr cur_lock, prev_lock;
+};
+
+DECLARE_WAYFIRE_PLUGIN(wf_session_lock_plugin);
diff --git a/plugins/single_plugins/ipc-rules.cpp b/plugins/single_plugins/ipc-rules.cpp
index 414902289..4010f5330 100644
--- a/plugins/single_plugins/ipc-rules.cpp
+++ b/plugins/single_plugins/ipc-rules.cpp
@@ -66,6 +66,9 @@ static std::string layer_to_string(std::optional layer)
return "unmanaged";
case wf::scene::layer::OVERLAY:
+ return "overlay";
+
+ case wf::scene::layer::LOCK:
return "lock";
case wf::scene::layer::DWIDGET:
diff --git a/plugins/single_plugins/wsets.cpp b/plugins/single_plugins/wsets.cpp
index a141efa69..05b132f8b 100644
--- a/plugins/single_plugins/wsets.cpp
+++ b/plugins/single_plugins/wsets.cpp
@@ -9,7 +9,9 @@
#include "wayfire/view.hpp"
#include "plugins/ipc/ipc-helpers.hpp"
#include "plugins/ipc/ipc-method-repository.hpp"
+#include "wayfire/plugins/common/cairo-util.hpp"
#include "wayfire/plugins/common/shared-core-data.hpp"
+#include "wayfire/plugins/common/simple-text-node.hpp"
#include
#include
#include
@@ -21,63 +23,6 @@
#include
#include
#include
-#include
-
-class wset_output_overlay_t : public wf::scene::node_t
-{
- class render_instance_t : public wf::scene::simple_render_instance_t
- {
- public:
- using simple_render_instance_t::simple_render_instance_t;
-
- void render(const wf::render_target_t& target, const wf::region_t& region)
- {
- OpenGL::render_begin(target);
-
- auto g = self->get_bounding_box();
- for (auto box : region)
- {
- target.logic_scissor(wlr_box_from_pixman_box(box));
- OpenGL::render_texture(self->cr_text.tex.tex, target, g, glm::vec4(1.0f),
- OpenGL::TEXTURE_TRANSFORM_INVERT_Y);
- }
-
- OpenGL::render_end();
- }
- };
-
- wf::cairo_text_t cr_text;
-
- public:
- wset_output_overlay_t() : node_t(false)
- {}
-
- void gen_render_instances(std::vector& instances,
- wf::scene::damage_callback push_damage, wf::output_t *output) override
- {
- instances.push_back(std::make_unique(this, push_damage, output));
- }
-
- wf::geometry_t get_bounding_box() override
- {
- return wf::construct_box({10, 10}, cr_text.get_size());
- }
-
- void set_text(std::string text)
- {
- wf::cairo_text_t::params params;
- params.text_color = wf::color_t{0.9, 0.9, 0.9, 1};
- params.bg_color = wf::color_t{0.1, 0.1, 0.1, 0.9};
- params.font_size = 32;
- params.rounded_rect = true;
- params.bg_rect = true;
- params.max_size = wf::dimensions(get_bounding_box());
-
- cr_text.render_text(text, params);
- wf::scene::damage_node(this->shared_from_this(), get_bounding_box());
- }
-};
-
class wayfire_wsets_plugin_t : public wf::plugin_interface_t
@@ -187,7 +132,7 @@ class wayfire_wsets_plugin_t : public wf::plugin_interface_t
struct output_overlay_data_t : public wf::custom_data_t
{
- std::shared_ptr node;
+ std::shared_ptr node;
wf::wl_timer timer;
~output_overlay_data_t()
{
@@ -219,10 +164,15 @@ class wayfire_wsets_plugin_t : public wf::plugin_interface_t
auto overlay = wo->get_data_safe();
if (!overlay->node)
{
- overlay->node = std::make_shared();
+ overlay->node = std::make_shared();
}
overlay->node->set_text("Workspace set " + std::to_string(wo->wset()->get_index()));
+ overlay->node->set_position({10, 10});
+ overlay->node->set_text_params(wf::cairo_text_t::params(32 /* font_size */,
+ wf::color_t{0.1, 0.1, 0.1, 0.9} /* bg_color */,
+ wf::color_t{0.9, 0.9, 0.9, 1} /* fg_color */));
+
wf::scene::readd_front(wo->node_for_layer(wf::scene::layer::DWIDGET), overlay->node);
wf::scene::damage_node(overlay->node, overlay->node->get_bounding_box());
diff --git a/proto/meson.build b/proto/meson.build
index c08c7a51e..320285252 100644
--- a/proto/meson.build
+++ b/proto/meson.build
@@ -30,6 +30,7 @@ server_protocols = [
[wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml'],
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/input-method/input-method-unstable-v1.xml'],
+ [wl_protocol_dir, 'staging/ext-session-lock/ext-session-lock-v1.xml'],
'wayfire-shell-unstable-v2.xml',
'gtk-shell.xml',
'wlr-layer-shell-unstable-v1.xml',
diff --git a/src/api/wayfire/nonstd/wlroots-full.hpp b/src/api/wayfire/nonstd/wlroots-full.hpp
index ca309fb8b..b9e0c3f3e 100644
--- a/src/api/wayfire/nonstd/wlroots-full.hpp
+++ b/src/api/wayfire/nonstd/wlroots-full.hpp
@@ -137,6 +137,7 @@ extern "C"
#include
#include
#include
+#include
// Activation plugin
#include
diff --git a/src/api/wayfire/nonstd/wlroots.hpp b/src/api/wayfire/nonstd/wlroots.hpp
index 142e1e241..03a8f5a65 100644
--- a/src/api/wayfire/nonstd/wlroots.hpp
+++ b/src/api/wayfire/nonstd/wlroots.hpp
@@ -38,6 +38,7 @@ extern "C"
struct wlr_presentation;
struct wlr_primary_selection_v1_device_manager;
struct wlr_drm_lease_v1_manager;
+ struct wlr_session_lock_manager_v1;
struct wlr_xdg_foreign_v1;
struct wlr_xdg_foreign_v2;
diff --git a/src/api/wayfire/output.hpp b/src/api/wayfire/output.hpp
index 38415a4a2..afa603624 100644
--- a/src/api/wayfire/output.hpp
+++ b/src/api/wayfire/output.hpp
@@ -166,6 +166,17 @@ class output_t : public wf::object_base_t, public wf::signal::provider_t
*/
virtual bool is_plugin_active(std::string owner_name) const = 0;
+ /**
+ * Sets (or unsets) the output as inhibited, so that no plugins can be activated
+ * except those that ignore inhibitions.
+ */
+ void set_inhibited(bool inhibited);
+
+ /**
+ * Returns whether the output is inhibited..
+ */
+ bool is_inhibited() const;
+
/**
* Switch the workspace so that view becomes visible.
* @return true if workspace switch really occurred
@@ -198,6 +209,7 @@ class output_t : public wf::object_base_t, public wf::signal::provider_t
protected:
/* outputs are instantiated internally by core */
output_t();
+ bool inhibited = false;
};
/**
diff --git a/src/api/wayfire/scene.hpp b/src/api/wayfire/scene.hpp
index daeb84a24..9ffcb0ba3 100644
--- a/src/api/wayfire/scene.hpp
+++ b/src/api/wayfire/scene.hpp
@@ -414,8 +414,9 @@ enum class layer : size_t
TOP = 3,
UNMANAGED = 4,
OVERLAY = 5,
+ LOCK = 6,
// For compatibility with workspace-manager, to be removed
- DWIDGET = 6,
+ DWIDGET = 7,
/** Not a real layer, but a placeholder for the number of layers. */
ALL_LAYERS,
};
diff --git a/src/view/subsurface.hpp b/src/api/wayfire/unstable/wlr-subsurface-controller.hpp
similarity index 100%
rename from src/view/subsurface.hpp
rename to src/api/wayfire/unstable/wlr-subsurface-controller.hpp
diff --git a/src/view/surface-impl.hpp b/src/api/wayfire/unstable/wlr-surface-controller.hpp
similarity index 100%
rename from src/view/surface-impl.hpp
rename to src/api/wayfire/unstable/wlr-surface-controller.hpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 112560143..2aed053c5 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -30,7 +30,7 @@
#include
#include
-#include "view/surface-impl.hpp"
+#include "wayfire/unstable/wlr-surface-controller.hpp"
#include "wayfire/scene-input.hpp"
#include "opengl-priv.hpp"
#include "seat/input-manager.hpp"
diff --git a/src/core/scene.cpp b/src/core/scene.cpp
index ae293bbf9..3f935e229 100644
--- a/src/core/scene.cpp
+++ b/src/core/scene.cpp
@@ -177,6 +177,7 @@ std::string node_t::stringify() const
"top",
"unmanaged",
"overlay",
+ "lock",
"dwidget"
};
diff --git a/src/core/seat/drag-icon.cpp b/src/core/seat/drag-icon.cpp
index 3409646e9..e0fbc2321 100644
--- a/src/core/seat/drag-icon.cpp
+++ b/src/core/seat/drag-icon.cpp
@@ -1,5 +1,5 @@
#include "drag-icon.hpp"
-#include "view/surface-impl.hpp"
+#include "wayfire/unstable/wlr-surface-controller.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include "wayfire/core.hpp"
#include "wayfire/geometry.hpp"
diff --git a/src/core/seat/input-manager.cpp b/src/core/seat/input-manager.cpp
index cd1428589..a91153259 100644
--- a/src/core/seat/input-manager.cpp
+++ b/src/core/seat/input-manager.cpp
@@ -165,10 +165,9 @@ wf::input_manager_t::input_manager_t()
output_added.set_callback([=] (output_added_signal *ev)
{
- auto wo = (wf::output_impl_t*)ev->output;
if (exclusive_client != nullptr)
{
- wo->inhibit_plugins();
+ ev->output->set_inhibited(true);
}
refresh_device_mappings();
@@ -181,14 +180,7 @@ void wf::input_manager_t::set_exclusive_focus(wl_client *client)
exclusive_client = client;
for (auto& wo : wf::get_core().output_layout->get_outputs())
{
- auto impl = (wf::output_impl_t*)wo;
- if (client)
- {
- impl->inhibit_plugins();
- } else
- {
- impl->uninhibit_plugins();
- }
+ wo->set_inhibited(client != nullptr);
}
/* We no longer have an exclusively focused client, so we should restore
diff --git a/src/meson.build b/src/meson.build
index 7a4db2a97..41fbe43a7 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -35,8 +35,8 @@ wayfire_sources = ['geometry.cpp',
'core/seat/touch.cpp',
'core/seat/seat.cpp',
- 'view/surface.cpp',
- 'view/subsurface.cpp',
+ 'view/wlr-surface-controller.cpp',
+ 'view/wlr-subsurface-controller.cpp',
'view/view.cpp',
'view/toplevel-view.cpp',
'view/view-impl.cpp',
diff --git a/src/output/output-impl.hpp b/src/output/output-impl.hpp
index b9c260d9d..9861016ed 100644
--- a/src/output/output-impl.hpp
+++ b/src/output/output-impl.hpp
@@ -34,8 +34,6 @@ class output_impl_t : public output_t
wf::signal::connection_t on_configuration_changed;
void update_node_limits();
- bool inhibited = false;
-
wf::dimensions_t effective_size;
public:
@@ -64,20 +62,6 @@ class output_impl_t : public output_t
void add_activator(option_sptr_t activator, wf::activator_callback*) override;
void rem_binding(void *callback) override;
- /**
- * Set the output as inhibited, so that no plugins can be activated
- * except those that ignore inhibitions.
- */
- void inhibit_plugins();
-
- /**
- * Uninhibit the output.
- */
- void uninhibit_plugins();
-
- /** @return true if the output is inhibited */
- bool is_inhibited() const;
-
/** Set the effective resolution of the output */
void set_effective_size(const wf::dimensions_t& size);
};
diff --git a/src/output/output.cpp b/src/output/output.cpp
index bc985a98a..1dabafe81 100644
--- a/src/output/output.cpp
+++ b/src/output/output.cpp
@@ -361,18 +361,16 @@ bool wf::output_impl_t::is_plugin_active(std::string name) const
return false;
}
-void wf::output_impl_t::inhibit_plugins()
+void wf::output_t::set_inhibited(bool inhibited)
{
- this->inhibited = true;
- cancel_active_plugins();
-}
-
-void wf::output_impl_t::uninhibit_plugins()
-{
- this->inhibited = false;
+ this->inhibited = inhibited;
+ if (inhibited)
+ {
+ cancel_active_plugins();
+ }
}
-bool wf::output_impl_t::is_inhibited() const
+bool wf::output_t::is_inhibited() const
{
return this->inhibited;
}
diff --git a/src/view/view-impl.cpp b/src/view/view-impl.cpp
index 3f555b663..86062850f 100644
--- a/src/view/view-impl.cpp
+++ b/src/view/view-impl.cpp
@@ -1,4 +1,3 @@
-#include "view/surface-impl.hpp"
#include "wayfire/core.hpp"
#include "../core/core-impl.hpp"
#include "view-impl.hpp"
@@ -6,6 +5,7 @@
#include "wayfire/scene-render.hpp"
#include "wayfire/scene.hpp"
#include "wayfire/signal-definitions.hpp"
+#include "wayfire/unstable/wlr-surface-controller.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include "wayfire/view.hpp"
#include "wayfire/workspace-set.hpp"
diff --git a/src/view/view-impl.hpp b/src/view/view-impl.hpp
index 6ac7b830a..351df9189 100644
--- a/src/view/view-impl.hpp
+++ b/src/view/view-impl.hpp
@@ -7,10 +7,10 @@
#include
#include
-#include "surface-impl.hpp"
#include "wayfire/core.hpp"
#include "wayfire/nonstd/tracking-allocator.hpp"
#include "wayfire/signal-provider.hpp"
+#include "wayfire/unstable/wlr-surface-controller.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include "wayfire/output.hpp"
#include "wayfire/scene.hpp"
diff --git a/src/view/subsurface.cpp b/src/view/wlr-subsurface-controller.cpp
similarity index 97%
rename from src/view/subsurface.cpp
rename to src/view/wlr-subsurface-controller.cpp
index fdba77d5d..120884a5b 100644
--- a/src/view/subsurface.cpp
+++ b/src/view/wlr-subsurface-controller.cpp
@@ -1,10 +1,10 @@
-#include "subsurface.hpp"
#include "view/view-impl.hpp"
#include "wayfire/geometry.hpp"
#include "wayfire/scene-operations.hpp"
#include "wayfire/scene.hpp"
#include "wayfire/signal-definitions.hpp"
#include "wayfire/unstable/translation-node.hpp"
+#include "wayfire/unstable/wlr-subsurface-controller.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include
#include
diff --git a/src/view/surface.cpp b/src/view/wlr-surface-controller.cpp
similarity index 96%
rename from src/view/surface.cpp
rename to src/view/wlr-surface-controller.cpp
index 2b2f087d6..44e2de753 100644
--- a/src/view/surface.cpp
+++ b/src/view/wlr-surface-controller.cpp
@@ -1,8 +1,6 @@
#include
#include