fusuma-plugin-appmatcher 0.7.1 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0ff585f50332d6d07f2a160b9d940ae58d5f2fd6fee54b25289df480d5a2c04
4
- data.tar.gz: 1421a3f34917a949932aadad5c2d3343b12bf133a7abe2c1eacc0e9a13ce46f0
3
+ metadata.gz: 69bf1d29cc81954c8ceb160cbce4ce71da3156ba3f836a69285c01a3d31c2d8f
4
+ data.tar.gz: a912664d466fc86797d389e8608b6100aa748ee1dc82de65e2e272ef61c06acf
5
5
  SHA512:
6
- metadata.gz: d629c722c4caf82eba94e6ae3965bbb60c4df0b086277bfc3b1dd770fa73b07f27b23b7a1de5a9cc714d0c43ab3715788711f0e9903c2bb759c8c4c241816b51
7
- data.tar.gz: 6cf64e2d1ca08e64108db1735f002d15a4a8b29d77a1027b19e81a7ceb45505277629d819fe785acb07aced79655b40f185ca1666fe3f3439072880bfed6f28c
6
+ metadata.gz: 30c39974d22d5b64f5efd306e7abcab89937890b9b191705293da312b15ea0f4e39a8de3225791c07188c37b4b00e3620746a5fc271ebfb4273f3ac524336202
7
+ data.tar.gz: 15b900560a0ea3a084e2acda300ee0d3327262b4127396ee80988962257181792154973b47da229e0bc6d0706a64e2b5423c6aef43c460a54b9af7980b243bbb
data/README.md CHANGED
@@ -38,7 +38,7 @@ Google-chrome
38
38
  Alacritty
39
39
  ```
40
40
 
41
- You can use these applicatin name to under `application:` context in config.yml
41
+ You can use these application name to under `application:` context in config.yml
42
42
 
43
43
  ## Add appmatcher properties and application names to config.yml
44
44
 
@@ -20,13 +20,10 @@ module Fusuma
20
20
  # fork process and watch signal
21
21
  # @return [Integer] Process id
22
22
  def watch_start
23
- @watch_start ||= begin
24
- pid = as_user(proctitle: self.class.name.underscore) do |user|
25
- @reader.close
26
- ENV["DBUS_SESSION_BUS_ADDRESS"] = "unix:path=/run/user/#{user.uid}/bus"
27
- register_on_application_changed(Matcher.new)
28
- end
29
- pid
23
+ as_user(proctitle: self.class.name.underscore) do |user|
24
+ @reader.close
25
+ ENV["DBUS_SESSION_BUS_ADDRESS"] = "unix:path=/run/user/#{user.uid}/bus"
26
+ register_on_application_changed(Matcher.new)
30
27
  end
31
28
  end
32
29
 
@@ -2,7 +2,8 @@
2
2
  "name": "Appmatcher",
3
3
  "description": "notify focused application using D-Bus",
4
4
  "shell-version" : [
5
- "45"
5
+ "45",
6
+ "46"
6
7
  ],
7
8
  "url" : "https://github.com/iberianpig/fusuma-plugin-appmatcher",
8
9
  "uuid": "appmatcher@iberianpig.dev",
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "../user_switcher"
4
4
  require "fileutils"
5
+ require "yaml"
5
6
 
6
7
  module Fusuma
7
8
  module Plugin
@@ -11,24 +12,6 @@ module Fusuma
11
12
  class Installer
12
13
  include UserSwitcher
13
14
 
14
- EXTENSION = "./appmatcher@iberianpig.dev"
15
-
16
- def gnome_shell_extension_path
17
- output = `gnome-shell --version`
18
- version = output.match(/GNOME Shell (\d+\.\d+)/)
19
-
20
- if version
21
- version_number = version[1].to_f
22
- if version_number >= 45.0
23
- "./appmatcher45@iberianpig.dev"
24
- else
25
- "./appmatcher@iberianpig.dev"
26
- end
27
- else
28
- "./appmatcher@iberianpig.dev"
29
- end
30
- end
31
-
32
15
  def install
33
16
  pid = as_user(proctitle: self.class.name.underscore) do |user|
34
17
  FileUtils.cp_r(source_path, install_path(user.username))
@@ -52,18 +35,41 @@ module Fusuma
52
35
  File.exist?(install_path)
53
36
  end
54
37
 
38
+ def enabled?
39
+ enabled_extensions = YAML.load(`gsettings get org.gnome.shell enabled-extensions`)
40
+ enabled_extensions&.include?(EXTENSION)
41
+ end
42
+
55
43
  private
56
44
 
57
45
  def user_extension_dir(username = login_username)
58
46
  File.expand_path("#{Dir.home(username)}/.local/share/gnome-shell/extensions/")
59
47
  end
60
48
 
49
+ EXTENSION = "appmatcher@iberianpig.dev"
50
+ EXTENSION45 = "appmatcher45@iberianpig.dev"
61
51
  def install_path(username = login_username)
62
52
  File.expand_path("#{Dir.home(username)}/.local/share/gnome-shell/extensions/#{EXTENSION}")
63
53
  end
64
54
 
65
55
  def source_path
66
- File.expand_path(gnome_shell_extension_path, __dir__)
56
+ File.expand_path(gnome_shell_extension_filename, __dir__)
57
+ end
58
+
59
+ def gnome_shell_extension_filename
60
+ output = `gnome-shell --version`
61
+ version = output.match(/GNOME Shell (\d+\.\d+)/)
62
+
63
+ if version
64
+ version_number = version[1].to_f
65
+ if version_number >= 45.0
66
+ EXTENSION45
67
+ else
68
+ EXTENSION
69
+ end
70
+ else
71
+ EXTENSION
72
+ end
67
73
  end
68
74
 
69
75
  def login_username
@@ -22,19 +22,13 @@ module Fusuma
22
22
  # fork process and watch signal
23
23
  # @return [Integer] Process id
24
24
  def watch_start
25
- @watch_start ||= begin
26
- pid = as_user(proctitle: self.class.name.underscore) do
27
- @reader.close
28
- sleep # stop indefinitely without using CPU
29
- end
30
- pid
25
+ as_user(proctitle: self.class.name.underscore) do
26
+ @reader.close
27
+ sleep # stop indefinitely without using CPU
31
28
  end
32
29
  end
33
30
 
34
31
  class Matcher
35
- def initialize
36
- end
37
-
38
32
  def running_applications
39
33
  warn
40
34
  nil
@@ -3,7 +3,7 @@
3
3
  module Fusuma
4
4
  module Plugin
5
5
  module Appmatcher
6
- VERSION = "0.7.1"
6
+ VERSION = "0.9.0"
7
7
  end
8
8
  end
9
9
  end
@@ -21,12 +21,9 @@ module Fusuma
21
21
  # fork process and watch signal
22
22
  # @return [Integer] Process id
23
23
  def watch_start
24
- @watch_start ||= begin
25
- pid = as_user(proctitle: self.class.name.underscore) do |_user|
26
- @reader.close
27
- register_on_application_changed(Matcher.new)
28
- end
29
- pid
24
+ as_user(proctitle: self.class.name.underscore) do |_user|
25
+ @reader.close
26
+ register_on_application_changed(Matcher.new)
30
27
  end
31
28
  end
32
29
 
@@ -3,7 +3,6 @@
3
3
  require "fusuma/plugin/appmatcher/version"
4
4
 
5
5
  require "fusuma/plugin/appmatcher/x11"
6
- require "fusuma/plugin/appmatcher/gnome"
7
6
  require "fusuma/plugin/appmatcher/gnome_extension"
8
7
  require "fusuma/plugin/appmatcher/gnome_extensions/installer"
9
8
  require "fusuma/plugin/appmatcher/unsupported_backend"
@@ -22,12 +21,19 @@ module Fusuma
22
21
  when /wayland/
23
22
  case xdg_current_desktop
24
23
  when /GNOME/
25
- return GnomeExtension if GnomeExtensions::Installer.new.installed?
26
-
27
- return Gnome
24
+ if GnomeExtensions::Installer.new.enabled?
25
+ return GnomeExtension
26
+ else
27
+ MultiLogger.warn "Appmatcher Gnome Shell Extension is NOT enabled"
28
+ MultiLogger.warn "Please enable it by running the following command:"
29
+ MultiLogger.warn ""
30
+ MultiLogger.warn "$ fusuma-appmatcher --install-gnome-extension"
31
+ MultiLogger.warn ""
32
+ end
28
33
  end
29
34
  end
30
35
 
36
+ MultiLogger.warn "appmatcher doesn't support"
31
37
  UnsupportedBackend
32
38
  end
33
39
 
@@ -36,7 +42,7 @@ module Fusuma
36
42
  end
37
43
 
38
44
  def xdg_current_desktop
39
- ENV.fetch("XDG_CURRENT_DESKTOP", "")
45
+ ENV.fetch("ORIGINAL_XDG_CURRENT_DESKTOP", ENV.fetch("XDG_CURRENT_DESKTOP", ""))
40
46
  end
41
47
  end
42
48
  end
@@ -7,20 +7,16 @@ module Fusuma
7
7
  module Inputs
8
8
  # Get active application's name
9
9
  class AppmatcherInput < Input
10
- attr_reader :pid
11
-
12
10
  def io
13
- @backend ||= Appmatcher.backend_klass.new
11
+ return @io if instance_variable_defined?(:@io)
14
12
 
15
- @pid ||= begin
16
- pid = @backend.watch_start
17
- # NOTE: Closing the parent process's pipe
18
- @backend.writer.close
13
+ @backend = Appmatcher.backend_klass.new
19
14
 
20
- pid
21
- end
15
+ @backend.watch_start
16
+ # NOTE: Closing the parent process's pipe
17
+ @backend.writer.close
22
18
 
23
- @backend.reader
19
+ @io = @backend.reader
24
20
  end
25
21
 
26
22
  def shutdown
@@ -28,6 +24,7 @@ module Fusuma
28
24
  @backend.shutdown
29
25
  end
30
26
 
27
+ # TODO: use read_from_io
31
28
  # @param record [String] application name
32
29
  # @return [Event]
33
30
  def create_event(record:)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusuma-plugin-appmatcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - iberianpig
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-03 00:00:00.000000000 Z
11
+ date: 2025-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rexml
@@ -68,7 +68,6 @@ files:
68
68
  - exe/fusuma-appmatcher
69
69
  - fusuma-plugin-appmatcher.gemspec
70
70
  - lib/fusuma/plugin/appmatcher.rb
71
- - lib/fusuma/plugin/appmatcher/gnome.rb
72
71
  - lib/fusuma/plugin/appmatcher/gnome_extension.rb
73
72
  - lib/fusuma/plugin/appmatcher/gnome_extensions/appmatcher45@iberianpig.dev/extension.js
74
73
  - lib/fusuma/plugin/appmatcher/gnome_extensions/appmatcher45@iberianpig.dev/metadata.json
@@ -88,7 +87,7 @@ licenses:
88
87
  - MIT
89
88
  metadata:
90
89
  rubygems_mfa_required: 'true'
91
- post_install_message:
90
+ post_install_message:
92
91
  rdoc_options: []
93
92
  require_paths:
94
93
  - lib
@@ -103,8 +102,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
102
  - !ruby/object:Gem::Version
104
103
  version: '0'
105
104
  requirements: []
106
- rubygems_version: 3.4.10
107
- signing_key:
105
+ rubygems_version: 3.4.19
106
+ signing_key:
108
107
  specification_version: 4
109
108
  summary: Fusuma plugin to assign gesture mapping per application
110
109
  test_files: []
@@ -1,128 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require "dbus"
5
- require_relative "user_switcher"
6
-
7
- module Fusuma
8
- module Plugin
9
- module Appmatcher
10
- # Search Active Window's Name
11
- class Gnome
12
- include UserSwitcher
13
-
14
- attr_reader :reader, :writer
15
-
16
- def initialize
17
- @reader, @writer = IO.pipe
18
- end
19
-
20
- # fork process and watch signal
21
- # @return [Integer] Process id
22
- def watch_start
23
- @watch_start ||= begin
24
- pid = as_user(proctitle: self.class.name.underscore) do |user|
25
- @reader.close
26
- ENV["DBUS_SESSION_BUS_ADDRESS"] = "unix:path=/run/user/#{user.uid}/bus"
27
- register_on_application_changed(Matcher.new)
28
- end
29
- pid
30
- end
31
- end
32
-
33
- private
34
-
35
- def register_on_application_changed(matcher)
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 dbus
51
- class Matcher
52
- def initialize
53
- session_bus = DBus.session_bus
54
- service = session_bus.service("org.gnome.Shell")
55
- @interface = service["/org/gnome/Shell"]["org.gnome.Shell"]
56
- rescue DBus::Error => e
57
- MultiLogger.error "DBus::Error: #{e.message}"
58
-
59
- exit 1
60
- end
61
-
62
- # @return [Array<Application>]
63
- def running_applications
64
- gnome_shell_eval(
65
- <<~GJS
66
- global.get_window_actors().map(a => a.get_meta_window().get_wm_class());
67
- GJS
68
- )
69
- end
70
-
71
- def active_application
72
- # const index = global.get_window_actors()
73
- # .findIndex(a=>a.meta_window.has_focus()===true);
74
- # global.get_window_actors()[index].get_meta_window().get_wm_class();
75
- gnome_shell_eval(
76
- <<~GJS
77
- const actor = global.get_window_actors().find(a=>a.meta_window.has_focus()===true)
78
- actor && actor.get_meta_window().get_wm_class()
79
- GJS
80
- )
81
- end
82
-
83
- # TODO
84
- # def window_title
85
- # # const index = global.get_window_actors()
86
- # # .findIndex(a=>a.meta_window.has_focus()===true);
87
- # # global.get_window_actors()[index].get_meta_window().get_title();
88
- # gnome_shell_eval(
89
- # # <<~GJS
90
- # # global.get_window_actors().map((current) => {
91
- # # const wm_class = current.get_meta_window().get_wm_class();
92
- # # const title = current.get_meta_window().get_title();
93
- # # return { application: wm_class, window_title: title }
94
- # # })
95
- # # GJS
96
- # )
97
- # end
98
-
99
- def gnome_shell_eval(string)
100
- success, body = @interface.Eval(string)
101
-
102
- if success
103
- response = begin
104
- JSON.parse(body)
105
- rescue
106
- nil
107
- end
108
- return response
109
- end
110
-
111
- raise body
112
- end
113
-
114
- def on_active_application_changed
115
- loop do
116
- sleep 0.5
117
- new_application = active_application
118
- next if @old_application == new_application
119
-
120
- yield(new_application || "NOT FOUND") if block_given?
121
- @old_application = new_application
122
- end
123
- end
124
- end
125
- end
126
- end
127
- end
128
- end