How to detect file content changes using Gio

How can I detect file content changes or file modification using Gio? I’m trying to monitor changes in /sys/class/backlight/amdgpu_bl1/brightness file so that I can update the brightness level in my bar. So far I’ve tried this one but the handler never invokes when I change brightness with brightnessctl

screen_path = "/sys/class/backlight/amdgpu_bl1/brightness"
file = Gio.File.new_for_path(screen_path)
file_mon = file.monitor(Gio.FileMonitorFlags.NONE)

def screen_file_handler: print("brightness changed")

file_monitor.connect("changed", screen_file_handler)

sysfs doesn’t support inotify (et al.), so GFileMonitor won’t work.

You can look at how gnome-settings-daemon does this using udev uevents: plugins/power/gsd-backlight.c · master · GNOME / gnome-settings-daemon · GitLab

Alternatively, I believe you can just poll the file.

2 Likes

Yeah alternatively I can use python watchdog in that case. I guess FileMonitor only detects rename, move events etc.

Hi,

Can you try monitor_file? it works on my side (on standard files).

file_mon = file.monitor_file(Gio.FileMonitorFlags.NONE, None)

Note that some filesystems don’t properly notify Gio about file changes, it’s e.g. the case of the FUSE filesystem used by flatpak’s document portal. Maybe /sys is affected too?

1 Like

Try

def on_f_changed(file_monitor,g_file,other_file,event_type):
    if event_type == Gio.FileMonitorEvent.CHANGES_DONE_HINT:
        print("done")

g_file        =  Gio.File.new_for_path("/sys/class/backlight/amdgpu_bl1/brightness")
file_monitor  =  g_file.monitor_file(Gio.FileMonitorFlags.NONE)
file_monitor.set_rate_limit(800)
file_monitor.connect("changed",on_f_changed)
        

Gtk3 Example

1 Like

It works and so my previous solution. I’ve a project structure like this:

/home/xt/oniui
├── __init__.py
├── app.py
├── < more stuffs >
╰── Services
.....├── __init__.py
.....╰── Brightness.py

For some odd reason it works in app.py:

path = "/system/class/backlight/amdgpu_bl1/brightness"

file = Gio.File.new_for_path(screen_path)
file_mon = file.monitor_file(Gio.FileMonitorFlags.NONE, None)

def handler(*args): 
    print("changed")

file_mon.connect("changed", handler)

But when I do the same inside __init__ in Brightness.py and then import in app.py

from oniui.Services.Brightness import Brightness

brt = Brightness()

It doesn’t work

It does work if I put it inside app.py. But if I put the same code inside ./Services/Brightness.py and then import it then it doesn’t :slightly_frowning_face:

Could it be that you need to start the glib mainloop (e.g. by running the application) before creating the monitoring?

Maybe I guess. I got it working anyway using AstalIO from libastal (from the creator of Aylur’s Gtk Shell)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.