summaryrefslogtreecommitdiff
path: root/gui-wm/wayfire/files/wayfire-0.11.0-hedron-session.patch
blob: 0a72331f75224fc88b2da1856e006cee5c7c21ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
diff --git a/README.md b/README.md
index c5e6492..7cddb47 100644
--- a/README.md
+++ b/README.md
@@ -190,3 +190,16 @@ See the [Configuration] document for information on the options.
 ## Running
 
 Run [`wayfire`][Manual] from a TTY, or via a Wayland-compatible login manager.
+
+
+## 0.11.0-r78 (Hedron Sprint 3)
+
+The launcher selects the optional Hedron-owned seed for new accounts, preserving
+existing configs and the Wayfire fallback. Versioned launcher/desktop/helper
+inputs leave older ebuilds unchanged. Compatibility helpers prefer Hedron and
+fall back to legacy implementations. Login says Hedronfire; DesktopNames=Wayfire
+stays. No dependency on the shell is introduced.
+
+`wayfire/exit` schedules shutdown of this compositor after its response, with
+core/exit's inhibited-output guard. Config monitoring follows atomically
+replaced symlink targets again.
diff --git a/plugins/ipc/ipc.cpp b/plugins/ipc/ipc.cpp
index fd4f63f..3c12577 100644
--- a/plugins/ipc/ipc.cpp
+++ b/plugins/ipc/ipc.cpp
@@ -3,6 +3,9 @@
 #include <climits>
 #include <wayfire/util/log.hpp>
 #include <wayfire/core.hpp>
+#include <wayfire/seat.hpp>
+#include <wayfire/output.hpp>
+#include <wayfire/plugins/ipc/ipc-helpers.hpp>
 #include <wayfire/plugin.hpp>
 
 #include <fcntl.h>
@@ -406,6 +409,8 @@ class ipc_plugin_t : public wf::plugin_interface_t
 {
   private:
     shared_data::ref_ptr_t<ipc::server_t> server;
+    shared_data::ref_ptr_t<ipc::method_repository_t> methods;
+    wl_event_source* exit_idle = nullptr;
 
   public:
     void init() override
@@ -429,6 +434,29 @@ class ipc_plugin_t : public wf::plugin_interface_t
 
         setenv("WAYFIRE_SOCKET", socket.c_str(), 1);
         server->init(socket);
+        // Graceful logout is scoped to this IPC server's compositor. Defer
+        // shutdown until the response is sent; preserve core/exit's lock guard.
+        methods->register_method("wayfire/exit", [this] (const wf::json_t&)
+        {
+            auto output = wf::get_core().seat->get_active_output();
+            if (!output || output->is_inhibited()) return ipc::json_error("Session is inhibited");
+            if (!exit_idle) exit_idle = wl_event_loop_add_idle(wl_display_get_event_loop(wf::get_core().display),
+                [] (void* data)
+                {
+                    auto self = static_cast<ipc_plugin_t*>(data);
+                    self->exit_idle = nullptr;
+                    auto output = wf::get_core().seat->get_active_output();
+                    if (output && !output->is_inhibited()) wf::get_core().shutdown();
+                }, this);
+            return exit_idle ? ipc::json_ok() : ipc::json_error("Cannot schedule logout");
+        });
+    }
+
+    void fini() override
+    {
+        methods->unregister_method("wayfire/exit");
+        if (exit_idle) wl_event_source_remove(exit_idle);
+        exit_idle = nullptr;
     }
 
     bool is_unloadable() override
diff --git a/src/default-config-backend.cpp b/src/default-config-backend.cpp
index fb5b287..4b89ddf 100644
--- a/src/default-config-backend.cpp
+++ b/src/default-config-backend.cpp
@@ -23,7 +23,7 @@ static int wd_cfg_dir, wd_cfg_file;
 static void add_watch(int fd)
 {
     wd_cfg_dir  = inotify_add_watch(fd, config_dir.c_str(), IN_CREATE | IN_MOVED_TO);
-    wd_cfg_file = inotify_add_watch(fd, config_file.c_str(), IN_CLOSE_WRITE);
+    wd_cfg_file = inotify_add_watch(fd, config_file.c_str(), IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MOVE_SELF);
 }
 
 static const char *CONFIG_FILE_ENV = "WAYFIRE_CONFIG_FILE";
@@ -189,7 +189,17 @@ static int handle_config_updated(int fd, uint32_t mask, void *data)
         // We reload in two cases:
         //
         // 1. The config file itself was modified, or...
-        should_reload |= event->wd == wd_cfg_file;
+        if (event->wd == wd_cfg_file)
+        {
+            should_reload = true;
+            // Atomic saves may replace a symlink's target in a different
+            // directory. Follow the configured path again after replacement.
+            if (event->mask & (IN_DELETE_SELF | IN_MOVE_SELF))
+            {
+                if (!(event->mask & IN_DELETE_SELF)) inotify_rm_watch(fd, wd_cfg_file);
+                wd_cfg_file = inotify_add_watch(fd, config_file.c_str(), IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MOVE_SELF);
+            }
+        }
         // 2. The config file was moved nto or created inside the parent directory.
         if (event->len > 0)
         {
@@ -200,7 +210,7 @@ static int handle_config_updated(int fd, uint32_t mask, void *data)
             {
                 inotify_rm_watch(fd, wd_cfg_file);
                 wd_cfg_file =
-                    inotify_add_watch(fd, (config_dir + "/" + cfg_file_basename).c_str(), IN_CLOSE_WRITE);
+                    inotify_add_watch(fd, (config_dir + "/" + cfg_file_basename).c_str(), IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MOVE_SELF);
             }
 
             should_reload |= name_matches;