2424 "output-presets" ,
2525 "analyzer-levels" ,
2626)
27+ CURVE_STATUS_BY_PRESET_STATE = {
28+ "preset" : "preset" ,
29+ "modified" : "modified" ,
30+ "neutral" : "neutral" ,
31+ "unsaved" : "unsaved" ,
32+ }
33+ OUTPUT_PRESET_STATUS_LABELS = {
34+ "applied" : "Applied" ,
35+ "different" : "Different" ,
36+ "linked" : "Linked" ,
37+ "missing" : "Missing" ,
38+ "modified" : "Modified" ,
39+ }
2740
2841INTROSPECTION_XML = f"""
2942<node>
@@ -117,6 +130,93 @@ def quit_fully(self) -> None: ...
117130 def get_dbus_connection (self ) -> Gio .DBusConnection | None : ...
118131
119132
133+ def curve_status_from_preset_state (value : object ) -> str :
134+ return CURVE_STATUS_BY_PRESET_STATE .get (str (value or "" ).strip ().casefold (), "unknown" )
135+
136+
137+ def format_curve_label (name : str , status : str ) -> str :
138+ label = name .strip () or "Current State"
139+ if status == "modified" :
140+ return f"{ label } (modified)"
141+ return label
142+
143+
144+ def window_curve_display_state (window : object | None ) -> tuple [str , str , str ]:
145+ if window is None :
146+ return "" , "none" , "Current State"
147+
148+ curve_name = ""
149+ curve_status = "unknown"
150+ panel_state_factory = getattr (window , "preset_panel_ui_state" , None )
151+ if callable (panel_state_factory ):
152+ try :
153+ panel_state = panel_state_factory ()
154+ curve_name = str (getattr (panel_state , "current_curve_text" , "" ) or "" ).strip ()
155+ curve_status = curve_status_from_preset_state (getattr (panel_state , "preset_state_text" , "" ))
156+ except Exception :
157+ curve_name = ""
158+ curve_status = "unknown"
159+
160+ if not curve_name :
161+ curve_name = str (getattr (window , "current_preset_name" , "" ) or "" ).strip () or "Current State"
162+ if curve_status == "unknown" and getattr (window , "current_preset_name" , None ):
163+ curve_status = "preset"
164+
165+ return curve_name , curve_status , format_curve_label (curve_name , curve_status )
166+
167+
168+ def window_output_preset_link_name (window : object | None ) -> str :
169+ if window is None :
170+ return ""
171+
172+ output_preset_link_name = getattr (window , "output_preset_link_name" , None )
173+ if not callable (output_preset_link_name ):
174+ return ""
175+
176+ try :
177+ return str (output_preset_link_name () or "" ).strip ()
178+ except Exception :
179+ return ""
180+
181+
182+ def window_preset_name_exists (window : object , preset_name : str ) -> bool :
183+ preset_name_exists = getattr (window , "preset_name_exists" , None )
184+ if not callable (preset_name_exists ):
185+ return True
186+
187+ try :
188+ return bool (preset_name_exists (preset_name ))
189+ except Exception :
190+ return True
191+
192+
193+ def window_output_preset_status (window : object | None , preset_name : str ) -> str :
194+ if window is None or not preset_name :
195+ return "none"
196+
197+ if not window_preset_name_exists (window , preset_name ):
198+ return "missing"
199+ if bool (getattr (window , "output_preset_auto_applied" , False )):
200+ return "applied"
201+
202+ current_preset_name = getattr (window , "current_preset_name" , None )
203+ if current_preset_name == preset_name :
204+ return "modified"
205+ if current_preset_name :
206+ return "different"
207+ return "linked"
208+
209+
210+ def format_output_preset_label (preset_name : str , status : str ) -> str :
211+ if not preset_name :
212+ return ""
213+
214+ status_label = OUTPUT_PRESET_STATUS_LABELS .get (status )
215+ if status_label is None :
216+ return preset_name
217+ return f"{ status_label } - { preset_name } "
218+
219+
120220class MiniEqDbusControl :
121221 def __init__ (self , app : ApplicationProtocol ) -> None :
122222 self .app = app
@@ -148,11 +248,10 @@ def unregister(self) -> None:
148248 def state (self ) -> dict [str , GLib .Variant ]:
149249 controller = self .app .controller
150250 window = self .app .window
151- output_preset_name = ""
152- if window is not None :
153- output_preset_link_name = getattr (window , "output_preset_link_name" , None )
154- if output_preset_link_name is not None :
155- output_preset_name = output_preset_link_name () or ""
251+ curve_name , curve_status , curve_label = window_curve_display_state (window )
252+ output_preset_name = window_output_preset_link_name (window )
253+ output_preset_status = window_output_preset_status (window , output_preset_name )
254+ output_preset_label = format_output_preset_label (output_preset_name , output_preset_status )
156255
157256 return {
158257 "api_version" : GLib .Variant ("u" , API_VERSION ),
@@ -164,8 +263,13 @@ def state(self) -> dict[str, GLib.Variant]:
164263 "preset_name" : GLib .Variant (
165264 "s" , window .current_preset_name if window and window .current_preset_name else ""
166265 ),
266+ "curve_name" : GLib .Variant ("s" , curve_name ),
267+ "curve_status" : GLib .Variant ("s" , curve_status ),
268+ "curve_label" : GLib .Variant ("s" , curve_label ),
167269 "output_sink" : GLib .Variant ("s" , controller .output_sink if controller and controller .output_sink else "" ),
168270 "output_preset_name" : GLib .Variant ("s" , output_preset_name ),
271+ "output_preset_status" : GLib .Variant ("s" , output_preset_status ),
272+ "output_preset_label" : GLib .Variant ("s" , output_preset_label ),
169273 "output_preset_auto_applied" : GLib .Variant (
170274 "b" ,
171275 bool (window and getattr (window , "output_preset_auto_applied" , False )),
0 commit comments