fusuma-plugin-appmatcher 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/fusuma/plugin/appmatcher/hyprland.rb +118 -0
- data/lib/fusuma/plugin/appmatcher/version.rb +1 -1
- data/lib/fusuma/plugin/appmatcher.rb +14 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fbc93e3e0a8b5fb94642dc58a9b790fca024187e4d47af726b10662b352bd4ba
|
|
4
|
+
data.tar.gz: 77a6db018f3b2507618672d09ffc20609264ec2c514bffb996fae3b9ffa336ea
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b068878e2526e441fb7943f8e7b730d9fdfaa48ef710fb22bf917d1516e0143c2997bad952a0a9488633749e5125960d41982af99d899ba398369a2b20c05aa
|
|
7
|
+
data.tar.gz: 875ac50f1ecabd943d4591d01c7241e0a729381eb251427d945d61740d22a358b4a43d9d74dc0187cee0f20383ee82aaadad98d0713d67b62acdfe153c26bb17
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "socket"
|
|
4
|
+
require "json"
|
|
5
|
+
require_relative "user_switcher"
|
|
6
|
+
require "fusuma/multi_logger"
|
|
7
|
+
require "fusuma/custom_process"
|
|
8
|
+
|
|
9
|
+
module Fusuma
|
|
10
|
+
module Plugin
|
|
11
|
+
module Appmatcher
|
|
12
|
+
# Search Active Window's Name for Hyprland
|
|
13
|
+
class Hyprland
|
|
14
|
+
include UserSwitcher
|
|
15
|
+
|
|
16
|
+
attr_reader :reader, :writer
|
|
17
|
+
|
|
18
|
+
def initialize
|
|
19
|
+
@reader, @writer = IO.pipe
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# fork process and watch signal
|
|
23
|
+
# @return [Integer] Process id
|
|
24
|
+
def watch_start
|
|
25
|
+
as_user(proctitle: self.class.name.underscore) do |_user|
|
|
26
|
+
@reader.close
|
|
27
|
+
register_on_application_changed(Matcher.new)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def register_on_application_changed(matcher)
|
|
34
|
+
@writer.puts(matcher.active_application || "NOT FOUND")
|
|
35
|
+
|
|
36
|
+
matcher.on_active_application_changed do |name|
|
|
37
|
+
notify(name)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def notify(name)
|
|
42
|
+
@writer.puts(name)
|
|
43
|
+
rescue Errno::EPIPE
|
|
44
|
+
exit 0
|
|
45
|
+
rescue => e
|
|
46
|
+
MultiLogger.error e.message
|
|
47
|
+
exit 1
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Look up application name using hyprctl
|
|
51
|
+
class Matcher
|
|
52
|
+
ACTIVEWINDOW_EVENT = "activewindow"
|
|
53
|
+
|
|
54
|
+
# @return [Array<String>]
|
|
55
|
+
def running_applications
|
|
56
|
+
output = `hyprctl clients -j 2>/dev/null`
|
|
57
|
+
return [] if output.empty?
|
|
58
|
+
JSON.parse(output).map { |c| c["class"] }.compact.uniq
|
|
59
|
+
rescue JSON::ParserError
|
|
60
|
+
[]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [String, nil]
|
|
64
|
+
def active_application
|
|
65
|
+
output = `hyprctl -j activewindow 2>/dev/null`
|
|
66
|
+
return nil if output.empty? || output.strip == "{}"
|
|
67
|
+
JSON.parse(output)["class"]
|
|
68
|
+
rescue JSON::ParserError
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def on_active_application_changed
|
|
73
|
+
socket = connect_to_socket2
|
|
74
|
+
return unless socket
|
|
75
|
+
|
|
76
|
+
loop do
|
|
77
|
+
line = socket.gets
|
|
78
|
+
break unless line
|
|
79
|
+
|
|
80
|
+
event, data = line.chomp.split(">>", 2)
|
|
81
|
+
next unless event == ACTIVEWINDOW_EVENT
|
|
82
|
+
|
|
83
|
+
window_class, _window_title = data.split(",", 2)
|
|
84
|
+
yield(window_class.to_s.empty? ? "NOT FOUND" : window_class)
|
|
85
|
+
end
|
|
86
|
+
rescue Errno::ECONNRESET, Errno::EPIPE, IOError
|
|
87
|
+
# socket disconnected
|
|
88
|
+
ensure
|
|
89
|
+
socket&.close
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
# @return [String, nil]
|
|
95
|
+
def find_socket_path
|
|
96
|
+
instance_sig = ENV["HYPRLAND_INSTANCE_SIGNATURE"]
|
|
97
|
+
return nil unless instance_sig
|
|
98
|
+
|
|
99
|
+
xdg_runtime = ENV.fetch("XDG_RUNTIME_DIR", "/tmp")
|
|
100
|
+
[
|
|
101
|
+
File.join(xdg_runtime, "hypr", instance_sig, ".socket2.sock"),
|
|
102
|
+
File.join("/tmp", "hypr", instance_sig, ".socket2.sock")
|
|
103
|
+
].find { |p| File.exist?(p) }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# @return [UNIXSocket, nil]
|
|
107
|
+
def connect_to_socket2
|
|
108
|
+
path = find_socket_path
|
|
109
|
+
return nil unless path
|
|
110
|
+
UNIXSocket.new(path)
|
|
111
|
+
rescue Errno::ENOENT, Errno::ECONNREFUSED
|
|
112
|
+
nil
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -5,6 +5,7 @@ require "fusuma/plugin/appmatcher/version"
|
|
|
5
5
|
require "fusuma/plugin/appmatcher/x11"
|
|
6
6
|
require "fusuma/plugin/appmatcher/gnome_extension"
|
|
7
7
|
require "fusuma/plugin/appmatcher/gnome_extensions/installer"
|
|
8
|
+
require "fusuma/plugin/appmatcher/hyprland"
|
|
8
9
|
require "fusuma/plugin/appmatcher/unsupported_backend"
|
|
9
10
|
|
|
10
11
|
module Fusuma
|
|
@@ -30,6 +31,8 @@ module Fusuma
|
|
|
30
31
|
MultiLogger.warn "$ fusuma-appmatcher --install-gnome-extension"
|
|
31
32
|
MultiLogger.warn ""
|
|
32
33
|
end
|
|
34
|
+
when /Hyprland/i
|
|
35
|
+
return Hyprland if hyprland_available?
|
|
33
36
|
end
|
|
34
37
|
end
|
|
35
38
|
|
|
@@ -44,6 +47,17 @@ module Fusuma
|
|
|
44
47
|
def xdg_current_desktop
|
|
45
48
|
ENV.fetch("ORIGINAL_XDG_CURRENT_DESKTOP", ENV.fetch("XDG_CURRENT_DESKTOP", ""))
|
|
46
49
|
end
|
|
50
|
+
|
|
51
|
+
def hyprland_available?
|
|
52
|
+
instance_sig = ENV["HYPRLAND_INSTANCE_SIGNATURE"]
|
|
53
|
+
return false unless instance_sig
|
|
54
|
+
|
|
55
|
+
xdg_runtime = ENV.fetch("XDG_RUNTIME_DIR", "/tmp")
|
|
56
|
+
[
|
|
57
|
+
File.join(xdg_runtime, "hypr", instance_sig, ".socket2.sock"),
|
|
58
|
+
File.join("/tmp", "hypr", instance_sig, ".socket2.sock")
|
|
59
|
+
].any? { |p| File.exist?(p) }
|
|
60
|
+
end
|
|
47
61
|
end
|
|
48
62
|
end
|
|
49
63
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fusuma-plugin-appmatcher
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- iberianpig
|
|
@@ -74,6 +74,7 @@ files:
|
|
|
74
74
|
- lib/fusuma/plugin/appmatcher/gnome_extensions/appmatcher@iberianpig.dev/extension.js
|
|
75
75
|
- lib/fusuma/plugin/appmatcher/gnome_extensions/appmatcher@iberianpig.dev/metadata.json
|
|
76
76
|
- lib/fusuma/plugin/appmatcher/gnome_extensions/installer.rb
|
|
77
|
+
- lib/fusuma/plugin/appmatcher/hyprland.rb
|
|
77
78
|
- lib/fusuma/plugin/appmatcher/unsupported_backend.rb
|
|
78
79
|
- lib/fusuma/plugin/appmatcher/user_switcher.rb
|
|
79
80
|
- lib/fusuma/plugin/appmatcher/version.rb
|