Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nwg-displays for openSUSE:Factory 
checked in at 2026-08-28 19:47:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nwg-displays (Old)
 and      /work/SRC/openSUSE:Factory/.nwg-displays.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nwg-displays"

Fri Aug 28 19:47:50 2026 rev:11 rq:1374141 version:0.4.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/nwg-displays/nwg-displays.changes        
2026-07-17 01:42:46.615838771 +0200
+++ /work/SRC/openSUSE:Factory/.nwg-displays.new.1265/nwg-displays.changes      
2026-08-28 19:48:22.486057814 +0200
@@ -1,0 +2,7 @@
+Thu Aug 27 13:59:55 UTC 2026 - Nassim Lhadj <[email protected]>
+
+- Update to version 0.4.4:
+  * Fixed monitor descriptions with hashes in hyprland lua config #140
+  * Implemented Hyprland colorspace + VRR support #137
+
+-------------------------------------------------------------------

Old:
----
  nwg-displays-0.4.3.tar.gz

New:
----
  nwg-displays-0.4.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nwg-displays.spec ++++++
--- /var/tmp/diff_new_pack.nD6DYp/_old  2026-08-28 19:48:23.678099480 +0200
+++ /var/tmp/diff_new_pack.nD6DYp/_new  2026-08-28 19:48:23.681099585 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           nwg-displays
-Version:        0.4.3
+Version:        0.4.4
 Release:        0
 Summary:        Output management utility for sway, Hyprland and Niri
 License:        MIT

++++++ nwg-displays-0.4.3.tar.gz -> nwg-displays-0.4.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nwg-displays-0.4.3/.gitignore 
new/nwg-displays-0.4.4/.gitignore
--- old/nwg-displays-0.4.3/.gitignore   2026-05-13 03:16:43.000000000 +0200
+++ new/nwg-displays-0.4.4/.gitignore   2026-08-24 21:48:09.000000000 +0200
@@ -7,3 +7,4 @@
 __pycache__/
 /result
 /.vscode
+/.direnv
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nwg-displays-0.4.3/README.md 
new/nwg-displays-0.4.4/README.md
--- old/nwg-displays-0.4.3/README.md    2026-05-13 03:16:43.000000000 +0200
+++ new/nwg-displays-0.4.4/README.md    2026-08-24 21:48:09.000000000 +0200
@@ -86,7 +86,7 @@
 
 ### Hyprland
 
-[Monitors](https://wiki.hyprland.org/Configuring/Monitors):
+[Monitors](https://wiki.hyprland.org/0.54.0/Configuring/Monitors):
 
 Instead of configuring as described in Wiki, insert this line:
 
@@ -99,7 +99,7 @@
 require("monitors")
 ```
 
-[Default 
workspace](http://wiki.hyprland.org/Configuring/Monitors/#default-workspace) 
and [Binding workspaces to a 
monitor](https://wiki.hyprland.org/Configuring/Monitors/#binding-workspaces-to-a-monitor):
+[Default 
workspace](http://wiki.hyprland.org/0.54.0/Configuring/Monitors/#default-workspace)
 and [Binding workspaces to a 
monitor](https://wiki.hyprland.org/0.54.0/Configuring/Monitors/#binding-workspaces-to-a-monitor):
 
 Insert:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nwg-displays-0.4.3/nwg_displays/langs/en_US.json 
new/nwg-displays-0.4.4/nwg_displays/langs/en_US.json
--- old/nwg-displays-0.4.3/nwg_displays/langs/en_US.json        2026-05-13 
03:16:43.000000000 +0200
+++ new/nwg-displays-0.4.4/nwg_displays/langs/en_US.json        2026-08-24 
21:48:09.000000000 +0200
@@ -6,6 +6,14 @@
   "adaptive-sync-tooltip": "Enables or disables adaptive synchronization 
\n(often referred to as Variable Refresh Rate, \nor by the vendor-specific 
names FreeSync/G-Sync).",
   "apply": "Apply",
   "close": "Close",
+  "color-management": "Color",
+  "color-management-tooltip": "Color management preset (Hyprland only).\n'HDR' 
enables high dynamic range and forces 10-bit depth.\n'Wide' uses a wide color 
gamut (BT.2020 primaries).\n'EDID' uses the primaries reported by the display.",
+  "color-default": "Default",
+  "color-wide": "Wide gamut",
+  "sdr-brightness": "SDR brightness",
+  "sdr-brightness-tooltip": "Brightness multiplier for SDR content while in 
HDR mode \n(Hyprland only). Typical range 1.0–2.0.",
+  "sdr-saturation": "SDR saturation",
+  "sdr-saturation-tooltip": "Saturation multiplier for SDR content while in 
HDR mode \n(Hyprland only).",
   "custom-mode": "Custom mode",
   "custom-mode-tooltip": "Adds '--custom' argument to set a mode \nnot listed 
in the list of available modes.\nUse this ONLY  if you know what you're doing.",
   "dpms-tooltip": "Enables or disables output via DPMS. \nTo turn an output 
off (ie. blank the screen \nbut keep workspaces as-is), one can set DPMS to 
off.",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nwg-displays-0.4.3/nwg_displays/main.py 
new/nwg-displays-0.4.4/nwg_displays/main.py
--- old/nwg-displays-0.4.3/nwg_displays/main.py 2026-05-13 03:16:43.000000000 
+0200
+++ new/nwg-displays-0.4.4/nwg_displays/main.py 2026-08-24 21:48:09.000000000 
+0200
@@ -134,6 +134,9 @@
 form_version = None
 form_mirror = None
 form_ten_bit = None
+form_color_mode = None
+form_sdr_brightness = None
+form_sdr_saturation = None
 form_profile_wallpapers = None
 
 dialog_win = None
@@ -353,6 +356,13 @@
     form_refresh.set_value(widget.refresh)
     if form_ten_bit:
         form_ten_bit.set_active(widget.ten_bit)
+    if form_color_mode:
+        form_color_mode.set_active_id(widget.color_mode if widget.color_mode 
else "")
+        update_color_dependent_widgets(widget.color_mode)
+    if form_sdr_brightness:
+        form_sdr_brightness.set_value(widget.sdr_brightness)
+    if form_sdr_saturation:
+        form_sdr_saturation.set_value(widget.sdr_saturation)
     if form_mirror:
         form_mirror.remove_all()
         form_mirror.append("", voc["none"])
@@ -414,6 +424,9 @@
         focused,
         monitor,
         mirror="",
+        color_mode="",
+        sdr_brightness=1.0,
+        sdr_saturation=1.0,
     ):
         super().__init__()
         # Output properties
@@ -441,6 +454,10 @@
         self.focused = focused
         self.mirror = mirror
         self.ten_bit = ten_bit
+        # Color management (Hyprland only)
+        self.color_mode = color_mode
+        self.sdr_brightness = sdr_brightness
+        self.sdr_saturation = sdr_saturation
 
         # Button properties
         self.selected = False
@@ -535,6 +552,41 @@
         selected_output_button.ten_bit = check_btn.get_active()
 
 
+def is_hdr_mode(color_mode):
+    return color_mode in ["hdr", "hdredid"]
+
+
+def update_color_dependent_widgets(color_mode):
+    hdr = is_hdr_mode(color_mode)
+    # SDR brightness/saturation only take effect in HDR color modes
+    if form_sdr_brightness:
+        form_sdr_brightness.set_sensitive(hdr)
+    if form_sdr_saturation:
+        form_sdr_saturation.set_sensitive(hdr)
+    # HDR requires 10-bit: force the toggle on and lock it so the config stays 
valid
+    if form_ten_bit:
+        if hdr:
+            form_ten_bit.set_active(True)
+        form_ten_bit.set_sensitive(not hdr)
+
+
+def on_color_mode_changed(widget):
+    if selected_output_button:
+        color_mode = widget.get_active_id() or ""
+        selected_output_button.color_mode = color_mode
+        update_color_dependent_widgets(color_mode)
+
+
+def on_sdr_brightness_changed(widget):
+    if selected_output_button:
+        selected_output_button.sdr_brightness = round(widget.get_value(), 2)
+
+
+def on_sdr_saturation_changed(widget):
+    if selected_output_button:
+        selected_output_button.sdr_saturation = round(widget.get_value(), 2)
+
+
 def on_dpms_toggled(widget):
     if selected_output_button:
         selected_output_button.dpms = widget.get_active()
@@ -700,6 +752,9 @@
             item["focused"],
             item["monitor"],
             mirror=item["mirror"],
+            color_mode=item.get("color_mode", ""),
+            sdr_brightness=item.get("sdr_brightness", 1.0),
+            sdr_saturation=item.get("sdr_saturation", 1.0),
         )
 
         display_buttons.append(b)
@@ -1307,7 +1362,9 @@
 
     global form_adaptive_sync
     form_adaptive_sync = builder.get_object("adaptive-sync")
-    if sway:
+    # sway, Hyprland (vrr) and niri (variable-refresh-rate) all support 
per-output
+    # adaptive sync, so the toggle is available on all three.
+    if sway or hypr or niri:
         form_adaptive_sync.set_label(voc["adaptive-sync"])
         form_adaptive_sync.set_tooltip_text(voc["adaptive-sync-tooltip"])
         form_adaptive_sync.connect("toggled", on_adaptive_sync_toggled)
@@ -1488,6 +1545,58 @@
         form_mirror.connect("changed", on_mirror_selected)
         grid.attach(form_mirror, 7, 4, 1, 1)
 
+    if hypr:
+        # Color management / HDR controls (Hyprland only)
+        grid.insert_row(5)
+
+        lbl = Gtk.Label.new("{}:".format(voc["color-management"]))
+        lbl.set_property("halign", Gtk.Align.END)
+        grid.attach(lbl, 0, 5, 1, 1)
+
+        global form_color_mode
+        form_color_mode = Gtk.ComboBoxText()
+        form_color_mode.set_wrap_width(1)
+        form_color_mode.set_tooltip_text(voc["color-management-tooltip"])
+        for cm_id, cm_label in [
+            ("", voc["color-default"]),
+            ("auto", "Auto"),
+            ("srgb", "sRGB"),
+            ("wide", voc["color-wide"]),
+            ("edid", "EDID"),
+            ("hdr", "HDR"),
+            ("hdredid", "HDR (EDID)"),
+        ]:
+            form_color_mode.append(cm_id, cm_label)
+        form_color_mode.set_active_id("")
+        form_color_mode.connect("changed", on_color_mode_changed)
+        grid.attach(form_color_mode, 1, 5, 1, 1)
+
+        lbl = Gtk.Label.new("{}:".format(voc["sdr-brightness"]))
+        lbl.set_property("halign", Gtk.Align.END)
+        grid.attach(lbl, 2, 5, 1, 1)
+
+        global form_sdr_brightness
+        adj_b = Gtk.Adjustment(
+            value=1.0, lower=0.0, upper=2.0, step_increment=0.01, 
page_increment=0.1
+        )
+        form_sdr_brightness = Gtk.SpinButton.new(adj_b, 0.01, 2)
+        form_sdr_brightness.set_tooltip_text(voc["sdr-brightness-tooltip"])
+        form_sdr_brightness.connect("value-changed", on_sdr_brightness_changed)
+        grid.attach(form_sdr_brightness, 3, 5, 1, 1)
+
+        lbl = Gtk.Label.new("{}:".format(voc["sdr-saturation"]))
+        lbl.set_property("halign", Gtk.Align.END)
+        grid.attach(lbl, 4, 5, 1, 1)
+
+        global form_sdr_saturation
+        adj_s = Gtk.Adjustment(
+            value=1.0, lower=0.0, upper=2.0, step_increment=0.01, 
page_increment=0.1
+        )
+        form_sdr_saturation = Gtk.SpinButton.new(adj_s, 0.01, 2)
+        form_sdr_saturation.set_tooltip_text(voc["sdr-saturation-tooltip"])
+        form_sdr_saturation.connect("value-changed", on_sdr_saturation_changed)
+        grid.attach(form_sdr_saturation, 5, 5, 1, 1)
+
     # Add profile management buttons
     separator = Gtk.Separator(orientation=Gtk.Orientation.VERTICAL)
     form_wrapper_box.pack_start(separator, False, False, 10)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nwg-displays-0.4.3/nwg_displays/profiles.py 
new/nwg-displays-0.4.4/nwg_displays/profiles.py
--- old/nwg-displays-0.4.3/nwg_displays/profiles.py     2026-05-13 
03:16:43.000000000 +0200
+++ new/nwg-displays-0.4.4/nwg_displays/profiles.py     2026-08-24 
21:48:09.000000000 +0200
@@ -313,6 +313,9 @@
                 "custom_mode": db.custom_mode,
                 "mirror": db.mirror,
                 "ten_bit": db.ten_bit,
+                "color_mode": getattr(db, "color_mode", ""),
+                "sdr_brightness": getattr(db, "sdr_brightness", 1.0),
+                "sdr_saturation": getattr(db, "sdr_saturation", 1.0),
                 "active": db.active,
             }
             profile_data["displays"].append(display)
@@ -398,6 +401,17 @@
                             if display.get("ten_bit") is not None
                             else False
                         )
+                        db.color_mode = display.get("color_mode", "") or ""
+                        db.sdr_brightness = float(
+                            display.get("sdr_brightness")
+                            if display.get("sdr_brightness") is not None
+                            else 1.0
+                        )
+                        db.sdr_saturation = float(
+                            display.get("sdr_saturation")
+                            if display.get("sdr_saturation") is not None
+                            else 1.0
+                        )
                         db.active = (
                             display.get("active")
                             if display.get("active") is not None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nwg-displays-0.4.3/nwg_displays/settings_applier/settings_applier.py 
new/nwg-displays-0.4.4/nwg_displays/settings_applier/settings_applier.py
--- old/nwg-displays-0.4.3/nwg_displays/settings_applier/settings_applier.py    
2026-05-13 03:16:43.000000000 +0200
+++ new/nwg-displays-0.4.4/nwg_displays/settings_applier/settings_applier.py    
2026-08-24 21:48:09.000000000 +0200
@@ -59,15 +59,14 @@
         print(f"[Profile] Applying {len(displays)} displays for Hyprland...")
 
         header = SettingsApplier._get_header("Profile Loader")
-        lines_conf = [header]
+        lines_conf = []
         lines_lua = [header.replace("#", "--")]
 
         for d in displays:
             if not use_desc:
                 name = d["name"]
             else:
-                desc_safe = d["description"].replace("#", "##")
-                name = f"desc:{desc_safe}"
+                name = f"desc:{d['description']}"
 
             lua_props = [f'    output = "{name}"']
 
@@ -98,10 +97,35 @@
                     conf_line += f",mirror,{d['mirror']}"
                     lua_props.append(f'    mirror = "{d["mirror"]}"')
 
-                if d.get("ten_bit"):
+                color_mode = d.get("color_mode") or ""
+                hdr = color_mode in ("hdr", "hdredid")
+
+                # HDR requires 10-bit; force it even if not explicitly stored
+                if d.get("ten_bit") or hdr:
                     conf_line += ",bitdepth,10"
                     lua_props.append("    bitdepth = 10")
 
+                if color_mode:
+                    conf_line += f",cm,{color_mode}"
+                    lua_props.append(f'    cm = "{color_mode}"')
+                    if hdr:
+                        sdr_brightness = d.get("sdr_brightness", 1.0)
+                        sdr_saturation = d.get("sdr_saturation", 1.0)
+                        if sdr_brightness != 1.0:
+                            conf_line += f",sdrbrightness,{sdr_brightness}"
+                            lua_props.append(f"    sdrbrightness = 
{sdr_brightness}")
+                        if sdr_saturation != 1.0:
+                            conf_line += f",sdrsaturation,{sdr_saturation}"
+                            lua_props.append(f"    sdrsaturation = 
{sdr_saturation}")
+
+                # Adaptive sync (VRR). The toggle mirrors the monitor's 
effective
+                # state, so writing it explicitly is safe and keeps the toggle 
working.
+                # note: hyprland can also accept 2 or 3 to enable 
fullscreen-only VRR;
+                # may need to add that in the future
+                vrr = "1" if d.get("adaptive_sync") else "0"
+                conf_line += f",vrr,{vrr}"
+                lua_props.append(f"    vrr = {vrr}")
+
                 lines_conf.append(conf_line)
 
                 if d["transform"] != "normal":
@@ -121,6 +145,8 @@
             else "~/.config/hypr/monitors.lua"
         )
 
+        lines_conf = [header] + [ln.replace("#", "##") for ln in lines_conf]
+
         save_list_to_text_file(lines_conf, outputs_path)
         save_list_to_text_file(lines_lua, outputs_path_lua)
 
@@ -426,15 +452,11 @@
         }
 
         header = SettingsApplier._get_header()
-        lines_conf = [header]
+        lines_conf = []
         lines_lua = [header.replace("#", "--")]
 
         for db in display_buttons:
-            name = (
-                db.name
-                if not use_desc
-                else "desc:{}".format(db.description.replace("#", "##"))
-            )
+            name = db.name if not use_desc else 
"desc:{}".format(db.description)
 
             lua_props = [f'    output = "{name}"']
 
@@ -457,10 +479,33 @@
                     conf_line += f",mirror,{db.mirror}"
                     lua_props.append(f'    mirror = "{db.mirror}"')
 
-                if db.ten_bit:
+                color_mode = getattr(db, "color_mode", "") or ""
+                hdr = color_mode in ("hdr", "hdredid")
+
+                # HDR requires 10-bit; force it even if the checkbox is off
+                if db.ten_bit or hdr:
                     conf_line += ",bitdepth,10"
                     lua_props.append("    bitdepth = 10")
 
+                if color_mode:
+                    conf_line += f",cm,{color_mode}"
+                    lua_props.append(f'    cm = "{color_mode}"')
+                    if hdr:
+                        sdr_brightness = getattr(db, "sdr_brightness", 1.0)
+                        sdr_saturation = getattr(db, "sdr_saturation", 1.0)
+                        if sdr_brightness != 1.0:
+                            conf_line += f",sdrbrightness,{sdr_brightness}"
+                            lua_props.append(f"    sdrbrightness = 
{sdr_brightness}")
+                        if sdr_saturation != 1.0:
+                            conf_line += f",sdrsaturation,{sdr_saturation}"
+                            lua_props.append(f"    sdrsaturation = 
{sdr_saturation}")
+
+                # Adaptive sync (VRR). The toggle mirrors the monitor's 
effective
+                # state, so writing it explicitly is safe and keeps the toggle 
working.
+                vrr = "1" if db.adaptive_sync else "0"
+                conf_line += f",vrr,{vrr}"
+                lua_props.append(f"    vrr = {vrr}")
+
                 lines_conf.append(conf_line)
 
                 if db.transform != "normal":
@@ -488,6 +533,8 @@
         if os.path.isfile(outputs_path_lua):
             backup_lua = load_text_file(outputs_path_lua).splitlines()
 
+        lines_conf = [header] + [ln.replace("#", "##") for ln in lines_conf]
+
         save_list_to_text_file(lines_conf, outputs_path)
         save_list_to_text_file(lines_lua, outputs_path_lua)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nwg-displays-0.4.3/nwg_displays/tools.py 
new/nwg-displays-0.4.4/nwg_displays/tools.py
--- old/nwg-displays-0.4.3/nwg_displays/tools.py        2026-05-13 
03:16:43.000000000 +0200
+++ new/nwg-displays-0.4.4/nwg_displays/tools.py        2026-08-24 
21:48:09.000000000 +0200
@@ -188,6 +188,10 @@
                     "adaptive_sync_status": "enabled" if 
mon.get("vrr_enabled", False) else "disabled",
                     "mirror": "",
                     "ten_bit": False,
+                    # Color management is Hyprland-only; keep neutral defaults 
elsewhere
+                    "color_mode": "",
+                    "sdr_brightness": 1.0,
+                    "sdr_saturation": 1.0,
                     "monitor": None,
                     # Store raw make/model for matching
                     "__niri_make": raw_make,
@@ -246,6 +250,10 @@
 
                 outputs_dict[item.name]["mirror"] = ""  # We only use it on 
Hyprland
                 outputs_dict[item.name]["ten_bit"] = False  # We have no way 
to check it on sway
+                # Color management is Hyprland-only; keep neutral defaults 
elsewhere
+                outputs_dict[item.name]["color_mode"] = ""
+                outputs_dict[item.name]["sdr_brightness"] = 1.0
+                outputs_dict[item.name]["sdr_saturation"] = 1.0
                 outputs_dict[item.name]["monitor"] = None
 
     elif os.getenv("HYPRLAND_INSTANCE_SIGNATURE"):
@@ -317,6 +325,14 @@
 
             outputs_dict[m["name"]]["ten_bit"] = True if m["currentFormat"] in 
["XRGB2101010", "XBGR2101010"] else False
 
+            # Color management (Hyprland only). "srgb" is the implicit 
default, so
+            # treat it (and anything unknown) as "no cm line" to avoid 
touching configs
+            # that never opted into color management.
+            cm = m.get("colorManagementPreset", "")
+            outputs_dict[m["name"]]["color_mode"] = cm if cm in ["auto", 
"wide", "edid", "hdr", "hdredid"] else ""
+            outputs_dict[m["name"]]["sdr_brightness"] = 
float(m.get("sdrBrightness", 1.0))
+            outputs_dict[m["name"]]["sdr_saturation"] = 
float(m.get("sdrSaturation", 1.0))
+
             # to identify Gdk.Monitor
             outputs_dict[m["name"]]["model"] = m["model"]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nwg-displays-0.4.3/setup.py 
new/nwg-displays-0.4.4/setup.py
--- old/nwg-displays-0.4.3/setup.py     2026-05-13 03:16:43.000000000 +0200
+++ new/nwg-displays-0.4.4/setup.py     2026-08-24 21:48:09.000000000 +0200
@@ -9,7 +9,7 @@
 
 setup(
     name="nwg-displays",
-    version="0.4.3",
+    version="0.4.4",
     description="nwg-shell output configuration utility",
     packages=find_packages(),
     include_package_data=True,

Reply via email to