├── .github ├── sfwbar-dark.png ├── sfwbar-mpd.png ├── sfwbar-oneline.png ├── sfwbar-preview.png ├── sfwbar-switch.png ├── sfwbar-tray.png ├── sfwbar.png └── workflows │ ├── coverity.yml │ ├── freebsd.yml │ └── main.yml ├── LICENSE ├── README.md ├── config ├── alsa-module.widget ├── alsa.widget ├── backlight.widget ├── battery-svg.widget ├── battery.widget ├── bluez-popup.widget ├── bluez.widget ├── cal.widget ├── clock.widget ├── cpu-temp.source ├── cpu-temp.widget ├── cpu.source ├── cpu.widget ├── fan-rpm.widget ├── idle.widget ├── lan-bps.widget ├── mb-temp.widget ├── memory.source ├── memory.widget ├── mpd-intmod.widget ├── mpd-mini.widget ├── mpd-module.widget ├── mpd.source ├── mpd.widget ├── ncenter.widget ├── network-module.widget ├── oneline.config ├── privacy.widget ├── rfkill-bt.widget ├── rfkill-wifi.widget ├── rfkill.source ├── sfwbar.config ├── showdesktop.widget ├── startmenu.source ├── startmenu.widget ├── swap.source ├── sway-lang.widget ├── switcher.config ├── t2.config ├── test.config ├── test.widget ├── test2.config ├── twoline.config ├── usage.widget ├── vertical.config ├── volume.widget ├── w10.config ├── wbar-backlight.widget ├── wbar-battery.widget ├── wbar-bluetooth.widget ├── wbar-cpu.widget ├── wbar-idleinhibit.widget ├── wbar-memory.widget ├── wbar-mpd.widget ├── wbar-net.widget ├── wbar-pulse.widget ├── wbar-sway-lang.widget ├── wbar-temp.widget ├── wbar.config ├── weather.widget ├── wifi.widget └── winops.widget ├── data └── desktop-directories │ ├── AudioVideo.directory │ ├── Development.directory │ ├── Education.directory │ ├── Game.directory │ ├── Graphics.directory │ ├── Network.directory │ ├── Office.directory │ ├── Settings.directory │ ├── System-Tools.directory │ ├── Utility-Accessibility.directory │ └── Utility.directory ├── doc ├── ChangeLog ├── sfwbar-appmenu.1 ├── sfwbar-appmenu.rst ├── sfwbar-bluez.1 ├── sfwbar-bluez.rst ├── sfwbar-bsdctl.1 ├── sfwbar-bsdctl.rst ├── sfwbar-idle.1 ├── sfwbar-idle.rst ├── sfwbar-idleinhibit.1 ├── sfwbar-idleinhibit.rst ├── sfwbar-mpd.1 ├── sfwbar-mpd.rst ├── sfwbar-ncenter.1 ├── sfwbar-ncenter.rst ├── sfwbar-network.1 ├── sfwbar-network.rst ├── sfwbar-volume.1 ├── sfwbar-volume.rst ├── sfwbar-widgets.1 ├── sfwbar-widgets.rst ├── sfwbar-wifi.1 ├── sfwbar-wifi.rst ├── sfwbar-xkbmap.1 ├── sfwbar-xkbmap.rst ├── sfwbar.1 └── sfwbar.rst ├── icons ├── misc │ ├── comp.svg │ ├── cpu.svg │ ├── fan.svg │ ├── fforward.svg │ ├── lan.svg │ ├── lock.svg │ ├── missing.svg │ ├── music-player-symbolic.svg │ ├── music-player.svg │ ├── play.svg │ ├── rewind.svg │ ├── stop.svg │ └── unlock.svg ├── sfwbar.svg └── weather │ ├── LICENSE │ ├── clearsky_day.svg │ ├── clearsky_night.svg │ ├── clearsky_polartwilight.svg │ ├── cloudy.svg │ ├── fair_day.svg │ ├── fair_night.svg │ ├── fair_polartwilight.svg │ ├── fog.svg │ ├── heavyrain.svg │ ├── heavyrainandthunder.svg │ ├── heavyrainshowers_day.svg │ ├── heavyrainshowers_night.svg │ ├── heavyrainshowers_polartwilight.svg │ ├── heavyrainshowersandthunder_day.svg │ ├── heavyrainshowersandthunder_night.svg │ ├── heavyrainshowersandthunder_polartwilight.svg │ ├── heavysleet.svg │ ├── heavysleetandthunder.svg │ ├── heavysleetshowers_day.svg │ ├── heavysleetshowers_night.svg │ ├── heavysleetshowers_polartwilight.svg │ ├── heavysleetshowersandthunder_day.svg │ ├── heavysleetshowersandthunder_night.svg │ ├── heavysleetshowersandthunder_polartwilight.svg │ ├── heavysnow.svg │ ├── heavysnowandthunder.svg │ ├── heavysnowshowers_day.svg │ ├── heavysnowshowers_night.svg │ ├── heavysnowshowers_polartwilight.svg │ ├── heavysnowshowersandthunder_day.svg │ ├── heavysnowshowersandthunder_night.svg │ ├── heavysnowshowersandthunder_polartwilight.svg │ ├── lightrain.svg │ ├── lightrainandthunder.svg │ ├── lightrainshowers_day.svg │ ├── lightrainshowers_night.svg │ ├── lightrainshowers_polartwilight.svg │ ├── lightrainshowersandthunder_day.svg │ ├── lightrainshowersandthunder_night.svg │ ├── lightrainshowersandthunder_polartwilight.svg │ ├── lightsleet.svg │ ├── lightsleetandthunder.svg │ ├── lightsleetshowers_day.svg │ ├── lightsleetshowers_night.svg │ ├── lightsleetshowers_polartwilight.svg │ ├── lightsnow.svg │ ├── lightsnowandthunder.svg │ ├── lightsnowshowers_day.svg │ ├── lightsnowshowers_night.svg │ ├── lightsnowshowers_polartwilight.svg │ ├── lightssleetshowersandthunder_day.svg │ ├── lightssleetshowersandthunder_night.svg │ ├── lightssleetshowersandthunder_polartwilight.svg │ ├── lightssnowshowersandthunder_day.svg │ ├── lightssnowshowersandthunder_night.svg │ ├── lightssnowshowersandthunder_polartwilight.svg │ ├── partlycloudy_day.svg │ ├── partlycloudy_night.svg │ ├── partlycloudy_polartwilight.svg │ ├── rain.svg │ ├── rainandthunder.svg │ ├── rainshowers_day.svg │ ├── rainshowers_night.svg │ ├── rainshowers_polartwilight.svg │ ├── rainshowersandthunder_day.svg │ ├── rainshowersandthunder_night.svg │ ├── rainshowersandthunder_polartwilight.svg │ ├── sleet.svg │ ├── sleetandthunder.svg │ ├── sleetshowers_day.svg │ ├── sleetshowers_night.svg │ ├── sleetshowers_polartwilight.svg │ ├── sleetshowersandthunder_day.svg │ ├── sleetshowersandthunder_night.svg │ ├── sleetshowersandthunder_polartwilight.svg │ ├── snow.svg │ ├── snowandthunder.svg │ ├── snowshowers_day.svg │ ├── snowshowers_night.svg │ ├── snowshowers_polartwilight.svg │ ├── snowshowersandthunder_day.svg │ ├── snowshowersandthunder_night.svg │ └── snowshowersandthunder_polartwilight.svg ├── meson.build ├── meson.h.meson ├── meson_options.txt ├── modules ├── alsactl.c ├── appmenu.c ├── bluez.c ├── bsdctl.c ├── idle.c ├── idleinhibit.c ├── mpd.c ├── ncenter.c ├── network.c ├── pipewire.c ├── pulsectl.c ├── wifi-iwd.c ├── wifi-nm.c └── xkbmap.c ├── packaging ├── PKGBUILD ├── freebsd │ ├── Makefile │ ├── distinfo │ ├── files │ │ └── pkg-message.in │ ├── pkg-descr │ └── pkg-plist ├── sfwbar-1.0_beta10.ebuild └── sfwbar.spec ├── po ├── LINGUAS ├── meson.build ├── pl.po ├── ru.po ├── sfwbar.pot ├── zh_CN.po └── zh_TW.po ├── protocols ├── cosmic-workspace-unstable-v1.xml ├── ext-workspace-v1.xml ├── wlr-foreign-toplevel-management-unstable-v1.xml ├── wlr-layer-shell-unstable-v1.xml └── xdg-output-unstable-v1.xml └── src ├── actionlib.c ├── appinfo.c ├── appinfo.h ├── client.c ├── client.h ├── config ├── base.c ├── config.h ├── init.c ├── layout.c ├── menu.c ├── scanner.c └── toplevel.c ├── exprlib.c ├── gui ├── bar.c ├── bar.h ├── basewidget.c ├── basewidget.h ├── button.c ├── button.h ├── cchart.c ├── cchart.h ├── chart.c ├── chart.h ├── css.c ├── css.h ├── flowgrid.c ├── flowgrid.h ├── flowitem.c ├── flowitem.h ├── grid.c ├── grid.h ├── image.c ├── image.h ├── label.c ├── label.h ├── menu.c ├── menu.h ├── menuitem.c ├── menuitem.h ├── monitor.c ├── monitor.h ├── pager.c ├── pager.h ├── pageritem.c ├── pageritem.h ├── popup.c ├── popup.h ├── scale.c ├── scale.h ├── scaleimage.c ├── scaleimage.h ├── switcher.c ├── switcher.h ├── switcheritem.c ├── switcheritem.h ├── taskbar.c ├── taskbar.h ├── taskbaritem.c ├── taskbaritem.h ├── taskbarpager.c ├── taskbarpager.h ├── taskbarpopup.c ├── taskbarpopup.h ├── taskbarshell.c ├── taskbarshell.h ├── tray.c ├── tray.h ├── trayitem.c └── trayitem.h ├── ipc ├── cosmic-workspaces.c ├── ext-workspace.c ├── foreign-toplevel.c ├── hyprland.c ├── sway.c ├── sway.h └── wayfire.c ├── locale1.c ├── locale1.h ├── module.c ├── module.h ├── mpd.c ├── scanner.c ├── scanner.h ├── sfwbar.c ├── sfwbar.h ├── signal.c ├── sni.c ├── sni.h ├── sniitem.c ├── snimenu.c ├── trigger.c ├── trigger.h ├── util ├── datalist.c ├── datalist.h ├── file.c ├── file.h ├── json.c ├── json.h ├── string.c └── string.h ├── vm ├── expr.c ├── expr.h ├── func.c ├── parser.c ├── value.c ├── value.h ├── var.c ├── var.h ├── vm.c └── vm.h ├── wayland.c ├── wayland.h ├── window.c ├── window.h ├── wintree.c ├── wintree.h ├── workspace.c └── workspace.h /.github/sfwbar-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCrion/sfwbar/024b7ddca2109e6e14eef090749c4d0abd54994e/.github/sfwbar-dark.png -------------------------------------------------------------------------------- /.github/sfwbar-mpd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCrion/sfwbar/024b7ddca2109e6e14eef090749c4d0abd54994e/.github/sfwbar-mpd.png -------------------------------------------------------------------------------- /.github/sfwbar-oneline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCrion/sfwbar/024b7ddca2109e6e14eef090749c4d0abd54994e/.github/sfwbar-oneline.png -------------------------------------------------------------------------------- /.github/sfwbar-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCrion/sfwbar/024b7ddca2109e6e14eef090749c4d0abd54994e/.github/sfwbar-preview.png -------------------------------------------------------------------------------- /.github/sfwbar-switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCrion/sfwbar/024b7ddca2109e6e14eef090749c4d0abd54994e/.github/sfwbar-switch.png -------------------------------------------------------------------------------- /.github/sfwbar-tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCrion/sfwbar/024b7ddca2109e6e14eef090749c4d0abd54994e/.github/sfwbar-tray.png -------------------------------------------------------------------------------- /.github/sfwbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCrion/sfwbar/024b7ddca2109e6e14eef090749c4d0abd54994e/.github/sfwbar.png -------------------------------------------------------------------------------- /.github/workflows/coverity.yml: -------------------------------------------------------------------------------- 1 | # GitHub actions workflow. 2 | # https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions 3 | 4 | # https://scan.coverity.com/projects/openrc-openrc 5 | name: Coverity Scan 6 | 7 | on: 8 | push: 9 | branches: [main] 10 | 11 | jobs: 12 | coverity: 13 | runs-on: ubuntu-24.04 14 | steps: 15 | - uses: actions/checkout@v2 16 | - run: sudo apt-get update 17 | - run: sudo apt-get -y install libgtk-3-dev meson libgtk-layer-shell-dev libjson-c-dev libmpdclient-dev libpulse-dev 18 | - run: meson setup builddir/ -Dpulse=enabled -Dmpd=enabled -Dnetwork=enabled 19 | env: 20 | CC: gcc 21 | - uses: vapier/coverity-scan-action@v1 22 | with: 23 | command: ninja -C builddir 24 | email: ${{ secrets.COVERITY_SCAN_EMAIL }} 25 | token: ${{ secrets.COVERITY_SCAN_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/workflows/freebsd.yml: -------------------------------------------------------------------------------- 1 | name: FreeBSD_CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-24.04 8 | name: FreeBSD CI 9 | timeout-minutes: 20 10 | steps: 11 | - uses: actions/checkout@v3 12 | - name: Test in FreeBSD 13 | id: test 14 | uses: vmactions/freebsd-vm@v1 15 | with: 16 | usesh: true 17 | prepare: | 18 | pkg install -y curl meson ninja pkgconf gtk3 wayland-protocols gtk-layer-shell wayland json-c libmpdclient pulseaudio libxkbcommon alsa-lib 19 | 20 | run: | 21 | meson setup build --werror -Dpulse=enabled -Dmpd=enabled -Dnetwork=enabled -Dalsa=enabled -Dbluez=enabled -Dxkb=enabled -Didleinhibit=enabled -Dbsdctl=enabled 22 | ninja -C build 23 | DESTDIR=./install ninja -C build install 24 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the "main" branch 8 | push: 9 | branches: [ "main" ] 10 | pull_request: 11 | branches: [ "main" ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-24.04 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v3 27 | 28 | # Runs a set of commands using the runners shell 29 | - name: Run a multi-line script 30 | run: | 31 | sudo apt-get update 32 | sudo apt-get -y install libgtk-3-dev meson libgtk-layer-shell-dev libjson-c-dev libmpdclient-dev libpulse-dev bluez libbluetooth-dev libasound2-dev libxkbregistry-dev wayland-protocols gettext 33 | meson setup build --werror -Dpulse=enabled -Dmpd=enabled -Dnetwork=enabled -Dalsa=enabled -Dbluez=enabled -Dxkb=enabled -Didleinhibit=enabled 34 | ninja -C build 35 | DESTDIR=./install ninja -C build install 36 | -------------------------------------------------------------------------------- /config/alsa.widget: -------------------------------------------------------------------------------- 1 | scanner { 2 | ExecClient("stdbuf -oL amixer sevents","alsactl") {} 3 | Exec("amixer sget Master") { 4 | AlsaVolume = RegEx(".*[[](.[0-9]+)%") 5 | AlsaMuted = RegEx(".*[[].*[[]([A-Za-z].*)[]]") 6 | } 7 | } 8 | 9 | set AlsaMutedIcon = "audio-volume-muted-symbolic" 10 | set AlsaVolumeIcon = Lookup(AlsaVolume, 11 | 80, "audio-volume-high-symbolic", 12 | 50, "audio-volume-medium-symbolic", 13 | 0, "audio-volume-low-symbolic", 14 | $AlsaMutedIcon) 15 | set AlsaIcon = If($AlsaMuted = "off",$AlsaMutedIcon,$AlsaVolumeIcon) 16 | 17 | layout { 18 | style = "module" 19 | button { 20 | value = $AlsaIcon 21 | tooltip = GT("Volume") + ": " + Str(AlsaVolume,0) + "%" + If(AlsaMuted," (" + GT("muted") + ")","") 22 | style = If(Ident($AlsaVolume),"module","hidden") 23 | trigger = "alsactl" 24 | action[LeftClick] = Exec "amixer sset Master toggle\n" 25 | action[RightClick] = Exec $Term + " -e alsamixer" 26 | action[ScrollUp] = Exec "amixer sset Master 5%+\n" 27 | action[ScrollDown] = Exec "amixer sset Master 5%-\n" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /config/battery.widget: -------------------------------------------------------------------------------- 1 | define BatChargeStr = Str(10*BatLeft/BatTotal,0) 2 | define BatIcon = "battery-level-" + BatChargeStr + "0" + 3 | If($BatState = "Discharging","", 4 | If(BatChargeStr = "10","","-charging")) 5 | 6 | Function("BatteryInitScanner"){ 7 | PipeRead "/usr/bin/env python3 << END 8 | import os 9 | sysdir = '/sys/class/power_supply' 10 | list = os.scandir(sysdir) 11 | batdir='' 12 | for entry in list: 13 | if(entry.name.startswith('BAT')): 14 | batdir = os.path.join(sysdir,entry.name) 15 | if(batdir==''): 16 | exit(1) 17 | list = os.scandir(batdir) 18 | print('scanner {') 19 | for entry in list: 20 | if(entry.name.endswith('_full')): 21 | print('file(\"' + os.path.join(batdir,entry.name) + 22 | '\") { BatTotal = Grab(First) }') 23 | if(entry.name.endswith('_now') and 24 | ('charge' in entry.name or 'energy' in entry.name)): 25 | print('file(\"' + os.path.join(batdir,entry.name) + 26 | '\") { BatLeft = Grab(First) }') 27 | if(entry.name == 'status'): 28 | print('file(\"' + os.path.join(batdir,'status') + 29 | '\") { BatState = RegEx(\"^(.*)$\",First) }') 30 | print('}') 31 | END" 32 | SetValue "battery", BatIcon 33 | } 34 | 35 | layout { 36 | style = "module" 37 | button "battery" { 38 | action[0] = Function "BatteryInitScanner" 39 | style = If($BatState="","hidden","module") 40 | tooltip = Str(100*BatLeft/BatTotal,0) + "%" 41 | value = BatIcon 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /config/cpu-temp.source: -------------------------------------------------------------------------------- 1 | scanner { 2 | file("/sys/class/hwmon/hwmon1/temp1_input") { 3 | CPUTemp = Grab() 4 | } 5 | } 6 | 7 | module("bsdctl") 8 | 9 | Set BsdCPUTemp = BSDCtl("dev.cpu.0.temperature") 10 | Set XCpuTemp = If(!Ident(BSDCtl), CPUTemp/1000, BsdCPUTemp/10-273.2) 11 | Set XCpuTempPresent = If(Ident(BSDCtl), $BsdCPUTemp!="", CPUTemp.count) 12 | -------------------------------------------------------------------------------- /config/cpu-temp.widget: -------------------------------------------------------------------------------- 1 | include("cpu-temp.source") 2 | 3 | layout { 4 | css = "* { -GtkWidget-direction: right; -GtkWidget-vexpand: true; -GtkWidget-hexpand: true; }" 5 | image { 6 | style = "value_icon" 7 | value = "icons/misc/cpu.svg" 8 | } 9 | label { 10 | style = "value" 11 | interval = 1000 12 | value = Str(XCpuTemp, 0)+"°C" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /config/cpu.source: -------------------------------------------------------------------------------- 1 | # Add up CPU utilization stats across all CPUs 2 | scanner { 3 | file("/proc/stat") { 4 | CpuUser = RegEx("^cpu [\t ]*([0-9]+)",Sum) 5 | CpuNice = RegEx("^cpu [\t ]*[0-9]+ ([0-9]+)",Sum) 6 | CpuSystem = RegEx("^cpu [\t ]*(?:[0-9]+ ){2}([0-9]+)",Sum) 7 | CpuIdle = RegEx("^cpu [\t ]*(?:[0-9]+ ){3}([0-9]+)",Sum) 8 | } 9 | } 10 | 11 | module("bsdctl") 12 | 13 | Set XCpuBSD = BSDCtl("kern.cp_time") 14 | Set XCpuUser = If(!Ident(BSDCtl),CpuUser,Extract($XCpuBSD,"([0-9]+)")) 15 | Set XCpuSystem = If(!Ident(BSDCtl),CpuSystem,Extract($XCpuBSD,"[0-9]+ ([0-9]+)")) 16 | Set XCpuNice = If(!Ident(BSDCtl),CpuNice,Extract($XCpuBSD,"(?:[0-9]+ ){2}([0-9]+)")) 17 | Set XCpuIntr = If(!Ident(BSDCtl),0,Extract($XCpuBSD,"(?:[0-9]+ ){3}([0-9]+)")) 18 | Set XCpuIdle = If(!Ident(BSDCtl),CpuIdle,Extract($XCpuBSD,"(?:[0-9]+ ){4}([0-9]+)")) 19 | Set XCpuUtilization =(XCpuUser-XCpuUser.pval)/ 20 | (XCpuUser+XCpuNice+XCpuSystem+XCpuIntr+XCpuIdle- 21 | XCpuUser.pval-XCpuNice.pval-XCpuSystem.pval-XCpuIntr.pval-XCpuIdle.pval) 22 | Set XCpuPresent = If(Ident(BSDCtl),$XCpuBSD!="",CpuIdle.count) 23 | -------------------------------------------------------------------------------- /config/cpu.widget: -------------------------------------------------------------------------------- 1 | include("cpu.source") 2 | 3 | layout { 4 | chart { 5 | interval = 1000 6 | style = If(XCpuPresent,"cpu_chart","hidden") 7 | value = XCpuUtilization 8 | tooltip = "CPU: " + Str(XCpuUtilization*100) + '%' 9 | action = Exec $Term + " -e top" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /config/fan-rpm.widget: -------------------------------------------------------------------------------- 1 | scanner { 2 | # Poll CPU fan rpm 3 | file("/sys/devices/platform/it87*/hwmon/hwmon2/fan2_input") { 4 | CPUFan = Grab() 5 | } 6 | 7 | # Poll MB fan rpm 8 | file("/sys/devices/platform/it87*/hwmon/hwmon2/fan1_input") { 9 | MBFan = Grab() 10 | } 11 | } 12 | 13 | layout { 14 | css = "* { -GtkWidget-direction: right; -GtkWidget-vexpand: true; -GtkWidget-hexpand: true; }" 15 | image { 16 | style = "value_icon" 17 | value = "icons/misc/fan.svg" 18 | } 19 | label { 20 | style = "value" 21 | interval = 1000 22 | value = Str(CPUFan,0) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /config/idle.widget: -------------------------------------------------------------------------------- 1 | Module("idleinhibit"); 2 | 3 | layout { 4 | button { 5 | style = If(Ident(IdleInhibitState),"module","hidden") 6 | value = If(IdleInhibitState()="on", 7 | "icons/misc/lock.svg", 8 | "icons/misc/unlock.svg") 9 | local = true 10 | trigger = "idleinhibitor" 11 | action[1] = SetIdleInhibitor "toggle" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /config/lan-bps.widget: -------------------------------------------------------------------------------- 1 | scanner { 2 | # Add up received and transmitted bytes cross all enp* interfaces 3 | file("/proc/net/dev") { 4 | EthRcvd = RegEx("wlp.*:[\t ]*([0-9]+)",Sum) 5 | EthSent = RegEx("wlp.*:(?:[\t ]*[0-9]+){8}[\t ]([0-9]+)",Sum) 6 | } 7 | } 8 | 9 | layout { 10 | css = "* { -GtkWidget-direction: right; -GtkWidget-vexpand: true; -GtkWidget-hexpand: true; }" 11 | image { 12 | style = "value_icon" 13 | value = "icons/misc/lan.svg" 14 | } 15 | label { 16 | style = "value" 17 | interval = 1000 18 | value = Str((EthRcvd-EthRcvd.pval)/0.001024/EthRcvd.time,0)+"K/s" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /config/mb-temp.widget: -------------------------------------------------------------------------------- 1 | scanner { 2 | # Poll motherboard temperature 3 | file("/sys/class/hwmon/hwmon2/temp1_input") { 4 | MBTemp = Grab(First) 5 | } 6 | } 7 | 8 | layout { 9 | css = "* { -GtkWidget-direction: right; -GtkWidget-vexpand: true; -GtkWidget-hexpand: true; }" 10 | image { 11 | style = "value_icon" 12 | value = "icons/misc/comp.svg" 13 | } 14 | label { 15 | style = "value" 16 | interval = 1000 17 | value = Str(MBTemp/1000,0)+"C" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /config/memory.source: -------------------------------------------------------------------------------- 1 | scanner { 2 | file("/proc/meminfo") { 3 | MemTotal = RegEx("^MemTotal:[\t ]*([0-9]+)[\t ]") 4 | MemFree = RegEx("^MemFree:[\t ]*([0-9]+)[\t ]") 5 | MemCache = RegEx( "^Cached:[\t ]*([0-9]+)[\t ]") 6 | MemBuff = Regex("^Buffers:[\t ]*([0-9]+)[\t ]") 7 | } 8 | } 9 | 10 | module("bsdctl") 11 | 12 | Set XPageSize = BSDCtl("vm.stats.vm.v_page_size") 13 | Set XMemTotal = If(!Ident(BSDCtl),MemTotal,Val(BSDCtl("vm.stats.vm.v_page_count"))*XPageSize) 14 | Set XMemFree = If(!Ident(BSDCtl),MemFree,Val(BSDCtl("vm.stats.vm.v_free_count"))*XPageSize) 15 | Set XMemCache = If(!Ident(BSDCtl),MemCache,Val(BSDCtl("vm.stats.vm.v_inactive_count"))*XPageSize) 16 | Set XMemBuff = If(!Ident(BSDCtl),MemBuff,Val(BSDCtl("vm.stats.vm_laundry_count"))*XPageSize) 17 | Set XMemUtilization = (XMemTotal-XMemFree-XMemCache-XMemBuff)/XMemTotal 18 | Set XMemPresent = If(Ident(BSDCtl),$XPageSize!="",MemTotal.count) 19 | -------------------------------------------------------------------------------- /config/memory.widget: -------------------------------------------------------------------------------- 1 | include("memory.source") 2 | 3 | layout { 4 | scale { 5 | interval = 1000 6 | style = If(XMemPresent,"memory","hidden") 7 | value = XMemUtilization 8 | tooltip = GT("Memory") + ": " + Str(XMemUtilization*100) + "%" 9 | action = Exec $Term + " -e top -o %MEM" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /config/mpd-mini.widget: -------------------------------------------------------------------------------- 1 | Scanner { 2 | MpdClient("") { 3 | MpdTitle = RegEx("Title: (.*)") 4 | MpdArtist = RegEx("Artist: (.*)") 5 | MpdState = RegEx("state: (.*)") 6 | } 7 | } 8 | 9 | layout { 10 | style = If(MpdState.count=0,"hidden","frame") 11 | css = "* { -GtkWidget-direction: right; }" 12 | image { 13 | style="mpd" 14 | value = "icons/misc/rewind.svg" 15 | action = MpdCmd "previous" 16 | tooltip = $MpdArtist + "\n" + $MpdTitle 17 | } 18 | image { 19 | style="mpd" 20 | value = "icons/misc/play.svg" 21 | action = MpdCmd "play" 22 | tooltip = $MpdArtist + "\n" + $MpdTitle 23 | } 24 | image { 25 | style="mpd" 26 | value = "icons/misc/stop.svg" 27 | action = MpdCmd "stop" 28 | tooltip = $MpdArtist + "\n" + $MpdTitle 29 | } 30 | image { 31 | style="mpd" 32 | value = "icons/misc/fforward.svg" 33 | action = MpdCmd "next" 34 | tooltip = $MpdArtist + "\n" + $MpdTitle 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /config/mpd.source: -------------------------------------------------------------------------------- 1 | Scanner { 2 | MpdClient("") { 3 | MpdTitle = RegEx("Title: (.*)") 4 | MpdAlbum = RegEx("Album: (.*)") 5 | MpdArtist = RegEx("Artist: (.*)") 6 | MpdState = RegEx("state: (.*)") 7 | MpdRandom = RegEx("random:(.*)") 8 | MpdRepeat = RegEx("repeat:(.*)") 9 | MpdElapsed = RegEx("elapsed:(.*)") 10 | MpdDuration = RegEx("duration:(.*)") 11 | MpdVolume = RegEx("volume:(.*)") 12 | MpdQPos = RegEx("song: (.*)") 13 | MpdQLen = RegEx("playlistlength: (.*)") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /config/mpd.widget: -------------------------------------------------------------------------------- 1 | include("mpd.source") 2 | 3 | layout { 4 | style = If(MpdState.count=0,"hidden","frame") 5 | label { 6 | style = "mpd" 7 | interval = 100 8 | value = $MpdTitle 9 | loc(1,1,4,1) 10 | } 11 | label { 12 | style = "mpd" 13 | interval = 100 14 | value = $MpdArtist 15 | loc(1,2,4,1) 16 | } 17 | image { 18 | style="mpd" 19 | value = "icons/misc/rewind.svg" 20 | loc(1,3,1,1) 21 | action = MpdCmd "previous" 22 | } 23 | image { 24 | style="mpd" 25 | value = "icons/misc/play.svg" 26 | loc(2,3,1,1) 27 | action = MpdCmd "play" 28 | } 29 | image { 30 | style="mpd" 31 | value = "icons/misc/stop.svg" 32 | loc(3,3,1,1) 33 | action = MpdCmd "stop" 34 | } 35 | image { 36 | style="mpd" 37 | value = "icons/misc/fforward.svg" 38 | loc(4,3,1,1) 39 | action = MpdCmd "next" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /config/network-module.widget: -------------------------------------------------------------------------------- 1 | module("network") 2 | include("wifi.widget") 3 | 4 | Set XNetworkWifiSvg = ' 5 | 6 | 10 | 11 | 14 | 16 | 19 | 22 | ' 23 | 24 | Set XNetworkWirelessIcon = If(Ident(NetworkWirelessIcon),$NetworkWirelessIcon,$XNetworkWifiSvg) 25 | Set XNetworkWiredIcon = If(Ident(NetworkWiredIcon),$NetworkWiredIcon,"network-wired") 26 | Set XNetworkIcon = If(NetInfo("interface")="","network-error", 27 | If(NetInfo("essid")!="",$XNetworkWirelessIcon,$XNetworkWiredIcon)) 28 | 29 | layout { 30 | style = "module" 31 | button { 32 | value = $XNetworkIcon 33 | trigger = "network" 34 | action = PopUp "XWifiWindow" 35 | tooltip = "" + 36 | "interface: " + Pad(NetInfo("interface"),20) + "\n" + 37 | "ip: " + Pad(NetInfo("ip") + "/" + NetInfo("cidr"),20) + 38 | "\n" + 39 | "netmask: " + Pad(NetInfo("mask"),20) + "\n" + 40 | "gateway: " + Pad(NetInfo("gateway"),20) + "\n" + 41 | "essid: " + Pad(NetInfo("essid"),20) + "\n" + 42 | "signal: " + Pad(Str(NetStat("signal")) + "%",20) + 43 | "" 44 | style = If(Ident(NetInfo),"module","hidden") 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /config/privacy.widget: -------------------------------------------------------------------------------- 1 | module("pipewire") 2 | 3 | layout { 4 | button{ 5 | style = if(PipewireCount("AudioIn"), "module", "hidden") 6 | trigger = "pipewire" 7 | value = "audio-input-microphone"; 8 | css = "* { color: red; }" 9 | } 10 | button{ 11 | style = if(PipewireCount("VideoIn"), "module", "hidden") 12 | trigger = "pipewire" 13 | value = "camera-web"; 14 | css = "* { color: red; }" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /config/rfkill-bt.widget: -------------------------------------------------------------------------------- 1 | include("rfkill.source") 2 | 3 | 4 | layout { 5 | button { 6 | style = If(!XRfKillBTPresent, "hidden","module") 7 | value = If(XRfKillBTSoft = 1, 8 | "bluetooth-disabled", 9 | "bluetooth-active") 10 | tooltip = "Bluetooth: Soft" + If(XRfKillBTSoft,"","Un")+"blocked" + 11 | ", Hard" + If(XRfKillBTHard,"","Un")+"blocked" 12 | trigger = "rfkill" 13 | action = Exec "rfkill " + If(XRfKillBTSoft,"un","") + "block bluetooth" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /config/rfkill-wifi.widget: -------------------------------------------------------------------------------- 1 | include("rfkill.source") 2 | 3 | layout { 4 | button { 5 | style = If(!XRfKillWifiPresent, "hidden","module") 6 | value = If(XRfKillWifiSoft = 1, 7 | "network-wireless-hardware-disabled", 8 | "network-wireless-connected") 9 | tooltip = "WiFi: Soft" + If(XRfKillWifiSoft,"","Un")+"blocked" + 10 | ", Hard" + If(XRfKillWifiHard,"","Un")+"blocked" 11 | trigger = "rfkill" 12 | action = Exec "rfkill " + If(XRfKillWifiSoft,"un","") + "block wifi" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /config/rfkill.source: -------------------------------------------------------------------------------- 1 | scanner { 2 | ExecClient("stdbuf -oL rfkill event","rfkill") { 3 | RfkillWifiSoft = RegEx("type 1 op [0-9]+ soft ([0-9]+)") 4 | RfkillWifiHard = RegEx("type 1 op [0-9]+ soft [0-9]+ hard ([0-9]+)") 5 | RfkillBluetoothSoft = RegEx("type 2 op [0-9]+ soft ([0-9]+)") 6 | RfkillBluetoothHard = RegEx("type 2 op [0-9]+ soft [0-9]+ hard ([0-9]+)") 7 | } 8 | } 9 | 10 | Set XRfKillBTPresent = Cached(XRfKillBTPresent) | RfKillBluetoothSoft.count 11 | Set XRfKillBTSoft = If(RfKillBluetoothSoft.count, 12 | RfKillBluetoothSoft, 13 | Cached(XRfKillBTSoft)) 14 | Set XRfKillBTHard = If(RfKillBluetoothHard.count, 15 | RfKillBluetoothHard, 16 | Cached(XRfKillBTHard)) 17 | Set XRfKillWifiPresent = Cached(XRfKillWifiPresent) | RfKillWifiSoft.count 18 | Set XRfKillWifiSoft = If(RfKillWifiSoft.count, 19 | RfKillWifiSoft, 20 | Cached(XRfKillWifiSoft)) 21 | Set XRfKillWifiHard = If(RfKillWifiHard.count, 22 | RfKillWifiHard, 23 | Cached(XRfKillWifiHard)) 24 | -------------------------------------------------------------------------------- /config/showdesktop.widget: -------------------------------------------------------------------------------- 1 | Function ShowWindows() { 2 | Var i, wins; 3 | 4 | wins = WidgetChildren("target"); 5 | i = 0; 6 | While i (.*)") 4 | SwitchUserTool = RegEx(".*(.*)") 5 | } 6 | } 7 | 8 | layout { 9 | button { 10 | value = $SwitchUserIcon 11 | style = "app" 12 | action = Exec "./switchuser" 13 | tooltip = $SwitchUserTool 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /config/usage.widget: -------------------------------------------------------------------------------- 1 | include("cpu.source") 2 | include("memory.source") 3 | 4 | scanner { 5 | # Get total and remaining battery charge 6 | file("/sys/class/power_supply/BAT0/charge_full") { 7 | BatteryTotal = Grab(Sum) 8 | } 9 | file("/sys/class/power_supply/BAT0/charge_now") { 10 | BatteryLeft = Grab(Sum) 11 | } 12 | file("/sys/class/power_supply/AC/online") { 13 | ACOnline = Grab(Sum) 14 | } 15 | } 16 | 17 | layout { 18 | # add a sub-grid to house scales 19 | style = "scales" 20 | scale { 21 | style = if(XCpuPresent,"","hidden") 22 | css = "progressbar progress { background-color: #0000ff;}" 23 | value = XCpuUtilization 24 | } 25 | scale { 26 | style = if(XMemoryPresent,"","hidden") 27 | css = "progressbar progress { background-color: #00ff00;}" 28 | value= XMemoryUtilization 29 | } 30 | scale { 31 | value = BatteryLeft/BatteryTotal 32 | style = ACOnline 33 | css = "progressbar#1 progress { background-color: #ff0000;} \ 34 | progressbar#0 progress { background-color: #ffff00;}" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /config/wbar-backlight.widget: -------------------------------------------------------------------------------- 1 | scanner { 2 | file("/sys/class/backlight/*/actual_brightness") { 3 | BacklightActual = Grab(Sum) 4 | } 5 | file("/sys/class/backlight/*/max_brightness") { 6 | BacklightMax = Grab(Sum) 7 | } 8 | } 9 | 10 | module("bsdctl") 11 | 12 | Set XBacklight = If(!Ident(BSDCtl), 13 | BacklightActual/BacklightMax*100, 14 | Val(BSDCtl("hw.acpi.video.lcd0.brightness")) 15 | ) 16 | 17 | layout { 18 | label { 19 | style = "backlight" 20 | interval = 2000 21 | value = $XBacklight + '% ' 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /config/wbar-battery.widget: -------------------------------------------------------------------------------- 1 | scanner { 2 | file("/sys/class/power_supply/BAT0/charge_full") { 3 | BatteryTotal = Grab(Sum) 4 | } 5 | file("/sys/class/power_supply/BAT0/charge_now") { 6 | BatteryChargeNow = Grab(Sum) 7 | } 8 | file("/sys/class/power_supply/BAT0/energy_now") { 9 | BatteryEnergyNow = Grab(Sum) 10 | } 11 | file("/sys/class/power_supply/BAT0/status") { 12 | BatteryStatus = RegEx("^(.*)$") 13 | } 14 | } 15 | 16 | module("bsdctl") 17 | 18 | set BatteryLeft = If(BatteryChargeNow.count,BatteryChargeNow,BatteryEnergyNow) 19 | set XBatteryLevel = If(!Ident(BSDCtl), 20 | BatteryLeft / BatteryTotal * 100, 21 | BSDCtl("hw.acpi.battery.level.life") 22 | ) 23 | set XBatteryDischarging = If(!Ident(BSDCtl), 24 | $BatteryStatus="Discharging", 25 | BSDCtl("hw.acpi.battery.state")="1" 26 | ) 27 | 28 | layout { 29 | label { 30 | style = "battery" 31 | interval = 60000 32 | value = Str(XBatteryLevel) + '% ' + 33 | if(XBatteryDischarging, 34 | Lookup(XBatteryLevel,80,"",60,"",40,"",20,"",""), 35 | "") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /config/wbar-bluetooth.widget: -------------------------------------------------------------------------------- 1 | include("rfkill.source") 2 | 3 | Set RfKillBTVisible = Cached(RfKillBTVisible) | RfKillBluetoothSoft.count 4 | 5 | layout { 6 | label { 7 | style = If(RfKillBTVisible,"bluetooth","hidden") 8 | trigger = "rfkill" 9 | value = If(RfKillBluetoothSoft = 0," ","") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /config/wbar-cpu.widget: -------------------------------------------------------------------------------- 1 | include("cpu.source") 2 | 3 | layout { 4 | label { 5 | style = if(XCpuPresent,"cpu","hidden") 6 | interval = 10000 7 | value = Str(XCpuUtilization*100) + '% ' 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /config/wbar-idleinhibit.widget: -------------------------------------------------------------------------------- 1 | Module("idleinhibit"); 2 | 3 | layout { 4 | label { 5 | style = If(!Ident(IdleInhibitState),"hidden", 6 | If(IdleInhibitState()="on", 7 | "idle_inhibitor_activated", 8 | "idle_inhibitor")) 9 | value = If(IdleInhibitState()="on", 10 | "", 11 | "") 12 | tooltip = If(IdleInhibitState()="on", 13 | "activated", 14 | "deactivated") 15 | trigger = "idleinhibitor" 16 | action[1] = SetIdleInhibitor "toggle" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /config/wbar-memory.widget: -------------------------------------------------------------------------------- 1 | include("memory.source") 2 | 3 | layout { 4 | label { 5 | style = if(XMemPresent,"memory","hidden") 6 | interval = 30000 7 | value = Str(XMemUtilization*100) + '% ' 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /config/wbar-mpd.widget: -------------------------------------------------------------------------------- 1 | include("mpd.source") 2 | 3 | Set XMpdElapsed = MpdElapsed+If($MpdState="play",MpdElapsed.age/1000000,0) 4 | Set XMpdRandom = If(!MpdRandom,'','') 5 | 6 | function("SetMpd") { 7 | SetValue "Mpd", 8 | If($MpdState="disconnected", 9 | "Disconnected", 10 | Map($MpdState,"pause"," ","play","","") + 11 | $XMpdRandom + " "+ '' + If(!MpdRepeat,""," ")+ 12 | if($MpdState="stop","Stopped", 13 | $MpdArtist + " - " + 14 | $MpdAlbum + " - " + 15 | $MpdTitle + " (" + 16 | Pad(Str((XMpdElapsed-XMpdElapsed%60)/60),2,"0") + ":" + 17 | Pad(Str(XMpdElapsed%60),2,"0") + 18 | "/" + 19 | Pad(Str((MpdDuration-MpdDuration%60)/60),2,"0") + ":" + 20 | Pad(Str(MpdDuration%60),2,"0") + 21 | ") " + " ⸨" + $MpdQPos + "|" + $MpdQLen + "⸩ " + Str(MpdVolume) + "%" 22 | ) 23 | ) + " " 24 | } 25 | 26 | TriggerAction "mpd", Function "SetMpd" 27 | 28 | layout { 29 | label "Mpd" { 30 | interval = 1000 31 | style = Map($MpdState, 32 | "play", "mpd_play", 33 | "pause", "mpd_paused", 34 | "stop", "mpd_stopped", 35 | "mpd_disconnected" 36 | ) 37 | action[0] = Function "SetMpd" 38 | action = MpdCmd "pause" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /config/wbar-net.widget: -------------------------------------------------------------------------------- 1 | Module("network") 2 | 3 | function("ToggleNet") { 4 | [UserState] UserState "off" 5 | [UserState] SetValue 6 | If(NetInfo("ip")="", 7 | "Disconnected ⚠", 8 | NetInfo("interface") + ": " + NetInfo("ip") + "/" + NetInfo("cidr") 9 | ) 10 | [!UserState] UserState "on" 11 | [!UserState] SetValue 12 | If(NetInfo("ip")="", "Disconnected ⚠", 13 | If(NetInfo("Essid")="", 14 | NetInfo("ip") + ": " + NetInfo("cidr") + " ", 15 | NetInfo("Essid") + " (" + Str(NetStat("signal")) + "%) " 16 | ) 17 | ) 18 | } 19 | 20 | layout { 21 | label { 22 | style = If(Ident(NetInfo), 23 | If(NetInfo("ip")="", 24 | "network_disconnected", 25 | "network" 26 | ), 27 | "hidden" 28 | ) 29 | trigger = "network" 30 | action = Function "ToggleNet" 31 | action[0] = Function "ToggleNet" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /config/wbar-pulse.widget: -------------------------------------------------------------------------------- 1 | module("pulsectl") 2 | 3 | Set PulseIcon = Map(VolumeInfo("sink-form"), 4 | "headphone", "", 5 | "hands-free", "", 6 | "headset", "", 7 | "phone", "", 8 | "portable", "", 9 | "car", "", 10 | Lookup(Volume("sink-volume"),66,"",33,"","")) 11 | 12 | layout { 13 | label { 14 | style = If(Ident(Volume),If(Volume("sink-mute"),"pulseaudio_muted","pulseaudio"),"hidden") 15 | trigger = "volume" 16 | value = If(Volume("sink-mute"),"", Str(Volume("sink-volume")) + "% ") + 17 | $PulseIcon + " " + Str(Volume("source-volume")) + "% " 18 | action[4] = VolumeCtl "sink-volume +1" 19 | action[5] = VolumeCtl "sink-volume -1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /config/wbar-sway-lang.widget: -------------------------------------------------------------------------------- 1 | module("xkbmap") 2 | 3 | scanner { 4 | SwayClient("") { 5 | SwayXkbLayout = Json(".input.input.xkb_active_layout_name") 6 | } 7 | } 8 | 9 | Set XSwayLangCommand = If(Ident($SwayLangCommand),$SwayLangCommand, 10 | "input type:keyboard xkb_switch_layout next") 11 | 12 | Function("XSwayLangInit") { 13 | SwayCmd "input type:keyboard xkb_switch_layout next" 14 | SwayCmd "input type:keyboard xkb_switch_layout prev" 15 | } 16 | 17 | layout { 18 | label { 19 | action[0] = Function "XSwayLangInit" 20 | action[1] = SwayCmd $XSwayLangCommand 21 | style = If(Ident(SwayXkbLayout) & $SwayXkbLayout!="","language","hidden") 22 | value = XkbMap($SwayXkbLayout,"description","name") 23 | trigger = "sway" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /config/wbar-temp.widget: -------------------------------------------------------------------------------- 1 | include("cpu-temp.source") 2 | 3 | layout { 4 | label { 5 | style = if(XCpuTempPresent,"temperature","hidden") 6 | interval = 10000 7 | value = Str(XCPUTemp/1000)+'°C '+Lookup(XCpuTemp/1000,40,"",20,"","") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /config/weather.widget: -------------------------------------------------------------------------------- 1 | # Parse met.no weather forecast 2 | scanner { 3 | Exec("wget -O - \"https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=51.8711&lon=0.1587\"") { 4 | WthrTemp= Json(".properties.timeseries.1.data.instant.details.air_temperature") 5 | WthrCond= Json(".properties.timeseries.1.data.next_12_hours.summary.symbol_code") 6 | } 7 | } 8 | 9 | layout { 10 | style = "frame" 11 | label { 12 | interval = 300000 13 | css = "* { font: 0.5cm Sans; font-weight: 700; -GtkWidget-align: 0.5; padding-left: 1mm; padding-right: 1mm; }" 14 | value = Str(WthrTemp.val,1) 15 | } 16 | image { 17 | interval = 300000 18 | css = "* { -GtkWidget-hexpand: true; -GtkWidget-vexpand: true; padding-left: 1mm; padding-right: 1mm; }" 19 | value = 'icons/weather/'+$WthrCond+'.svg' 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /config/winops.widget: -------------------------------------------------------------------------------- 1 | function("ToggleMinimize") { 2 | [!Minimized] Minimize 3 | [Minimized] UnMinimize 4 | } 5 | 6 | function("ToggleMaximize") { 7 | [!Maximized] Maximize 8 | [Maximized] UnMaximize 9 | } 10 | 11 | menu("winops") { 12 | item(" "+GT("focus")+"%focus-windows-symbolic", Focus ); 13 | item(" "+GT("close")+"%window-close-symbolic", Close ); 14 | item(" "+GT("(un)minimize")+"%window-minimize-symbolic", Function "ToggleMinimize" ); 15 | item(" "+GT("(un)maximize")+"%window-maximize-symbolic", Function "ToggleMaximize" ); 16 | } 17 | -------------------------------------------------------------------------------- /data/desktop-directories/Education.directory: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name[af]=Opvoeding 3 | Name[ak]=Adesua 4 | Name[an]=Educacion 5 | Name[ar]=تعليمي 6 | Name[as]=শিক্ষা 7 | Name[ast]=Educación 8 | Name[be]=Адукацыя 9 | Name[be@latin]=Adukacyja 10 | Name[bg]=Обучение 11 | Name[bn]=শিক্ষা 12 | Name[bn_IN]=শিক্ষাবিষয়ক বস্তু 13 | Name[br]=Deskadurezh 14 | Name[bs]=Obrazovanje 15 | Name[ca]=Educació 16 | Name[ca@valencia]=Educació 17 | Name[ckb]=پەروەردە 18 | Name[crh]=Maarif 19 | Name[cs]=Vzdělávání 20 | Name[csb]=Ùczba 21 | Name[cy]=Addysg 22 | Name[da]=Læring 23 | Name[de]=Bildung 24 | Name[dv]=ތައުލީމު 25 | Name[dz]=ཤེས་རིག 26 | Name[el]=Εκπαίδευση 27 | Name[en_CA]=Education 28 | Name[en_GB]=Education 29 | Name[en@shaw]=𐑧𐑛𐑿𐑒𐑱𐑖𐑩𐑯 30 | Name[eo]=Edukado 31 | Name[es]=Educación 32 | Name[et]=Õppeprogrammid 33 | Name[eu]=Hezkuntza 34 | Name[fa]=آموزش 35 | Name[fi]=Opetusohjelmat 36 | Name[fr]=Éducation 37 | Name[fur]=Istruzion 38 | Name[fy]=Ûnderwiis 39 | Name[ga]=Oideachas 40 | Name[gd]=Foghlam 41 | Name[gl]=Educación 42 | Name[gn]=Arandu 43 | Name[gu]=શિક્ષણ 44 | Name[gv]=Ynsagh 45 | Name[ha]=Ilimi 46 | Name[he]=לימוד 47 | Name[hi]=शिक्षा 48 | Name[hr]=Obrazovanje 49 | Name[hu]=Oktatás 50 | Name[hy]=Ուսուցում 51 | Name[ia]=Education 52 | Name[id]=Pendidikan 53 | Name[ig]=Ọmụmụ 54 | Name[io]=Edukado 55 | Name[is]=Menntun 56 | Name[it]=Istruzione 57 | Name[ja]=教育・教養 58 | Name[ka]=განათლება 59 | Name[kab]=Asegmi 60 | Name[kg]=malongi 61 | Name[kk]=Оқыту 62 | Name[km]=ការ​អប់រំ 63 | Name[kn]=ಶಿಕ್ಷಣ 64 | Name[ko]=교육 65 | Name[ku]=Perwerdehî 66 | Name[ky]=Билим берүү 67 | Name[lo]=ການສຶກສາ 68 | Name[lt]=Švietimas 69 | Name[lv]=Izglītība 70 | Name[mai]=शिक्षा 71 | Name[mg]=Fanabeazana 72 | Name[mjw]=Locharli 73 | Name[mk]=Едукација 74 | Name[ml]=വിദ്യാഭ്യാസം 75 | Name[mn]=Боловсрол 76 | Name[mr]=शिक्षण 77 | Name[ms]=Pendidikan 78 | Name[nb]=Opplæring 79 | Name[nds]=Erteken 80 | Name[ne]=शिक्षा 81 | Name[nl]=Educatie 82 | Name[nn]=Utdanning 83 | Name[oc]=Educacion 84 | Name[or]=ଶିକ୍ଷା 85 | Name[pa]=ਸਿੱਖਿਆ 86 | Name[pl]=Nauka 87 | Name[ps]=زدکړه 88 | Name[pt]=Educação 89 | Name[pt_BR]=Educativo 90 | Name[ro]=Educație 91 | Name[ru]=Образовательные 92 | Name[si]=අධ්‍යාපනික 93 | Name[sk]=Vzdelávanie 94 | Name[sl]=Izobraževanje 95 | Name[sq]=Edukim 96 | Name[sr]=Образовање 97 | Name[sr@latin]=Obrazovanje 98 | Name[sv]=Utbildning 99 | Name[szl]=Edukacyjŏ 100 | Name[ta]=கல்வி 101 | Name[te]=విద్య 102 | Name[tg]=Маълумот 103 | Name[th]=การศึกษา 104 | Name[tr]=Eğitim 105 | Name[ug]=مائارىپ 106 | Name[uk]=Навчання 107 | Name[uz@cyrillic]=Таълим 108 | Name[vi]=Giáo dục 109 | Name[xh]=Imfundo 110 | Name[yo]=Ẹ̀kọ́ 111 | Name[zh_CN]=教育 112 | Name[zh_HK]=教育 113 | Name[zh_TW]=教育 114 | Name[zu]=Imfundo 115 | Name=Education 116 | # Translators: Do NOT translate or transliterate this text (this is an icon file name)! 117 | Icon=applications-science 118 | Type=Directory 119 | -------------------------------------------------------------------------------- /data/desktop-directories/Settings.directory: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Directory 3 | Name=Settings 4 | Name[af]=Instellings 5 | Name[ar]=الإعدادات 6 | Name[as]=বৈশিষ্ট্য 7 | Name[ast]=Configuración 8 | Name[az]=Ayarlar 9 | Name[be]=Налады 10 | Name[be@latin]=Nałady 11 | Name[bg]=Настройки 12 | Name[bn]=সেটিংস 13 | Name[bn_IN]=বিবিধ বৈশিষ্ট্য 14 | Name[br]=Dibarzhoù 15 | Name[bs]=Postavke 16 | Name[ca]=Preferències 17 | Name[ca@valencia]=Preferències 18 | Name[cs]=Nastavení 19 | Name[csb]=Ùstôw 20 | Name[cy]=Gosodiadau 21 | Name[da]=Indstillinger 22 | Name[de]=Einstellungen 23 | Name[el]=Ρυθμίσεις 24 | Name[en_GB]=Settings 25 | Name[eo]=Agordoj 26 | Name[es]=Preferencias 27 | Name[et]=Seadistused 28 | Name[eu]=Ezarpenak 29 | Name[fa]=تنظیمات 30 | Name[fi]=Asetukset 31 | Name[fr]=Configuration 32 | Name[fy]=Ynstellings 33 | Name[ga]=Socruithe 34 | Name[gl]=Configuración 35 | Name[gu]=ગોઠવણીઓ 36 | Name[he]=הגדרות 37 | Name[hi]=विन्यास 38 | Name[hne]=सेटिंग 39 | Name[hr]=Postavke 40 | Name[hsb]=Nastajenja 41 | Name[hu]=Beállítások 42 | Name[ia]=Preferentias 43 | Name[id]=Pengaturan 44 | Name[is]=Stillingar 45 | Name[it]=Impostazioni 46 | Name[ja]=設定 47 | Name[ka]=პარამეტრები 48 | Name[kk]=Параметрлері 49 | Name[km]=ការ​កំណត់ 50 | Name[kn]=ಸಂಯೋಜನೆಗಳು 51 | Name[ko]=설정 52 | Name[ku]=Mîheng 53 | Name[lt]=Nuostatos 54 | Name[lv]=Iestatījumi 55 | Name[mai]=जमावट 56 | Name[mk]=Поставувања 57 | Name[ml]=സജ്ജീകരണങ്ങള്‍ 58 | Name[mr]=संयोजना 59 | Name[ms]=Tempatan 60 | Name[nb]=Innstillinger 61 | Name[nds]=Instellen 62 | Name[ne]=सेटिङ 63 | Name[nl]=Instellingen 64 | Name[nn]=Innstillingar 65 | Name[oc]=Paramètres 66 | Name[or]=ସେଟିଙ୍ଗଗୁଡ଼ିକ 67 | Name[pa]=ਸੈਟਿੰਗਾਂ 68 | Name[pl]=Ustawienia 69 | Name[pt]=Configuração 70 | Name[pt_BR]=Configurações 71 | Name[ro]=Configurări 72 | Name[ru]=Настройка 73 | Name[sa]=समयोजनानि 74 | Name[si]=සැකසුම් 75 | Name[sk]=Nastavenia 76 | Name[sl]=Nastavitve 77 | Name[sr]=Поставке 78 | Name[sr@ijekavian]=Поставке 79 | Name[sr@ijekavianlatin]=Postavke 80 | Name[sr@latin]=Postavke 81 | Name[sv]=Inställningar 82 | Name[ta]=அமைப்புகள் 83 | Name[te]=అమరికలు 84 | Name[tg]=Танзимот 85 | Name[th]=ตั้งค่า 86 | Name[tr]=Ayarlar 87 | Name[ug]=تەڭشەكلەر 88 | Name[uk]=Параметри 89 | Name[uz]=Moslamalar 90 | Name[uz@cyrillic]=Мосламалар 91 | Name[vi]=Thiết lập 92 | Name[wa]=Apontiaedjes 93 | Name[x-test]=xxSettingsxx 94 | Name[zh_CN]=设置 95 | Name[zh_TW]=設定 96 | Icon=preferences-system 97 | -------------------------------------------------------------------------------- /doc/sfwbar-appmenu.1: -------------------------------------------------------------------------------- 1 | .\" Man page generated from reStructuredText. 2 | . 3 | . 4 | .nr rst2man-indent-level 0 5 | . 6 | .de1 rstReportMargin 7 | \\$1 \\n[an-margin] 8 | level \\n[rst2man-indent-level] 9 | level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] 10 | - 11 | \\n[rst2man-indent0] 12 | \\n[rst2man-indent1] 13 | \\n[rst2man-indent2] 14 | .. 15 | .de1 INDENT 16 | .\" .rstReportMargin pre: 17 | . RS \\$1 18 | . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] 19 | . nr rst2man-indent-level +1 20 | .\" .rstReportMargin post: 21 | .. 22 | .de UNINDENT 23 | . RE 24 | .\" indent \\n[an-margin] 25 | .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] 26 | .nr rst2man-indent-level -1 27 | .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] 28 | .in \\n[rst2man-indent\\n[rst2man-indent-level]]u 29 | .. 30 | .TH "SFWBAR-APPMENU" "1" "" "" 31 | .SH NAME 32 | sfwbar-appmenu \- Sfwbar Application menu module 33 | .sp 34 | Filename: appmenu.so 35 | .sp 36 | Requires: none 37 | .SH SYNOPSIS 38 | .sp 39 | The application menu module creates and maintains the applications menu object. 40 | This module has no triggers, actions or expression functions. The application 41 | menu is named \fIapp_menu_system\fP\&. 42 | .SH ACTIONS 43 | .SS AppMenuFilter Filename 44 | .sp 45 | Don\(aqt add a program with a .desktop file matching Filename. The Filename should 46 | include the .desktop extension. 47 | .SS AppMenuItemTop Title, Command 48 | .sp 49 | Add a custom item to the top of the application menu. The Title parameter is 50 | the name of the item (it can include a \(aq%\(aq separated icon name). The command 51 | is the command to execute upon the item activation. 52 | .SS AppMenuItemBottom Title, Command 53 | .sp 54 | Add a custom item to the bottom of the application menu. The parameters are 55 | the same as for AppMenuItemTop action. 56 | .SH COPYRIGHT 57 | GPLv3+ 58 | .\" Generated by docutils manpage writer. 59 | . 60 | -------------------------------------------------------------------------------- /doc/sfwbar-appmenu.rst: -------------------------------------------------------------------------------- 1 | sfwbar-appmenu 2 | ############## 3 | 4 | ############################## 5 | Sfwbar Application menu module 6 | ############################## 7 | 8 | :Copyright: GPLv3+ 9 | :Manual section: 1 10 | 11 | Filename: appmenu.so 12 | 13 | Requires: none 14 | 15 | SYNOPSIS 16 | ======== 17 | 18 | The application menu module creates and maintains the applications menu object. 19 | This module has no triggers, actions or expression functions. The application 20 | menu is named `app_menu_system`. 21 | 22 | Actions 23 | ======= 24 | 25 | AppMenuFilter Filename 26 | ---------------------- 27 | 28 | Don't add a program with a .desktop file matching Filename. The Filename should 29 | include the .desktop extension. 30 | 31 | 32 | AppMenuItemTop Title, Command 33 | ----------------------------- 34 | 35 | Add a custom item to the top of the application menu. The Title parameter is 36 | the name of the item (it can include a '%' separated icon name). The command 37 | is the command to execute upon the item activation. 38 | 39 | AppMenuItemBottom Title, Command 40 | -------------------------------- 41 | 42 | Add a custom item to the bottom of the application menu. The parameters are 43 | the same as for AppMenuItemTop action. 44 | -------------------------------------------------------------------------------- /doc/sfwbar-bsdctl.1: -------------------------------------------------------------------------------- 1 | .\" Man page generated from reStructuredText. 2 | . 3 | . 4 | .nr rst2man-indent-level 0 5 | . 6 | .de1 rstReportMargin 7 | \\$1 \\n[an-margin] 8 | level \\n[rst2man-indent-level] 9 | level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] 10 | - 11 | \\n[rst2man-indent0] 12 | \\n[rst2man-indent1] 13 | \\n[rst2man-indent2] 14 | .. 15 | .de1 INDENT 16 | .\" .rstReportMargin pre: 17 | . RS \\$1 18 | . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] 19 | . nr rst2man-indent-level +1 20 | .\" .rstReportMargin post: 21 | .. 22 | .de UNINDENT 23 | . RE 24 | .\" indent \\n[an-margin] 25 | .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] 26 | .nr rst2man-indent-level -1 27 | .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] 28 | .in \\n[rst2man-indent\\n[rst2man-indent-level]]u 29 | .. 30 | .TH "SFWBAR-BSDCTL" 1 "" "" "" 31 | .SH NAME 32 | sfwbar-bsdctl \- Sfwbar BSD sysctl module 33 | .sp 34 | Filename: bsdctl.so 35 | .sp 36 | Requires: BSD libc 37 | .SH SYNOPSIS 38 | .sp 39 | The BSDCtl module provides an interface to query BSD sysctl values 40 | .SH EXPRESSION FUNCTIONS 41 | .SS BSDCtl(Query) 42 | .sp 43 | function BSDCtl queries the value of a sysctl variable. It\(aqs equivalent to 44 | calling sysctl program on BSD system. Please note that you can only query 45 | individual nodes rather than groups. 46 | .SH ACTIONS 47 | .sp 48 | None 49 | .SH TRIGGERS 50 | .sp 51 | None 52 | .SH COPYRIGHT 53 | GPLv3+ 54 | .\" Generated by docutils manpage writer. 55 | . 56 | -------------------------------------------------------------------------------- /doc/sfwbar-bsdctl.rst: -------------------------------------------------------------------------------- 1 | sfwbar-bsdctl 2 | ############# 3 | 4 | ######################## 5 | Sfwbar BSD sysctl module 6 | ######################## 7 | 8 | :Copyright: GPLv3+ 9 | :Manual section: 1 10 | 11 | Filename: bsdctl.so 12 | 13 | Requires: BSD libc 14 | 15 | SYNOPSIS 16 | ======== 17 | 18 | The BSDCtl module provides an interface to query BSD sysctl values 19 | 20 | Expression Functions 21 | ==================== 22 | 23 | BSDCtl(Query) 24 | ------------- 25 | 26 | function BSDCtl queries the value of a sysctl variable. It's equivalent to 27 | calling sysctl program on BSD system. Please note that you can only query 28 | individual nodes rather than groups. 29 | 30 | Actions 31 | ======= 32 | 33 | None 34 | 35 | Triggers 36 | ======== 37 | 38 | None 39 | -------------------------------------------------------------------------------- /doc/sfwbar-idle.1: -------------------------------------------------------------------------------- 1 | .\" Man page generated from reStructuredText. 2 | . 3 | . 4 | .nr rst2man-indent-level 0 5 | . 6 | .de1 rstReportMargin 7 | \\$1 \\n[an-margin] 8 | level \\n[rst2man-indent-level] 9 | level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] 10 | - 11 | \\n[rst2man-indent0] 12 | \\n[rst2man-indent1] 13 | \\n[rst2man-indent2] 14 | .. 15 | .de1 INDENT 16 | .\" .rstReportMargin pre: 17 | . RS \\$1 18 | . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] 19 | . nr rst2man-indent-level +1 20 | .\" .rstReportMargin post: 21 | .. 22 | .de UNINDENT 23 | . RE 24 | .\" indent \\n[an-margin] 25 | .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] 26 | .nr rst2man-indent-level -1 27 | .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] 28 | .in \\n[rst2man-indent\\n[rst2man-indent-level]]u 29 | .. 30 | .TH "SFWBAR-IDLE" "1" "" "" 31 | .SH NAME 32 | sfwbar-idle \- Sfwbar Idle notifier module 33 | .sp 34 | Filename: idle.so 35 | .sp 36 | Requires: none 37 | .SH SYNOPSIS 38 | .sp 39 | The idle notifier module, provides support for idle triggers, i.e. triggers 40 | that are emitted if the user has been idle for a specified period of time. 41 | .SH EXPRESSION FUNCTIONS 42 | .sp 43 | None. 44 | .SH ACTIONS 45 | .SS IdleTimeout Trigger, Timeout 46 | .sp 47 | Create a new trigger with a name Trigger that will be emitted after Timeout 48 | seconds of idleness. I.e. \fIIdleTimeout \(dqtimeout1\(dq, \(dq10\(dq\fP\&. A trigger can be 49 | removed by invoking this action again with a Timeout value of zero. 50 | .SH TRIGGERS 51 | .sp 52 | The idle module defines trigger \fIresumed\fP by default. This trigger is emitted 53 | on the first user interaction after a timeout. Timeout triggers are defined 54 | using the \fIIdleTimeout\fP action. 55 | .SH COPYRIGHT 56 | GPLv3+ 57 | .\" Generated by docutils manpage writer. 58 | . 59 | -------------------------------------------------------------------------------- /doc/sfwbar-idle.rst: -------------------------------------------------------------------------------- 1 | sfwbar-idle 2 | ########### 3 | 4 | ########################### 5 | Sfwbar Idle notifier module 6 | ########################### 7 | 8 | :Copyright: GPLv3+ 9 | :Manual section: 1 10 | 11 | Filename: idle.so 12 | 13 | Requires: none 14 | 15 | SYNOPSIS 16 | ======== 17 | 18 | The idle notifier module, provides support for idle triggers, i.e. triggers 19 | that are emitted if the user has been idle for a specified period of time. 20 | 21 | Expression Functions 22 | ==================== 23 | 24 | None. 25 | 26 | Actions 27 | ======= 28 | 29 | IdleTimeout Trigger, Timeout 30 | ----------------------------- 31 | 32 | Create a new trigger with a name Trigger that will be emitted after Timeout 33 | seconds of idleness. I.e. `IdleTimeout "timeout1", "10"`. A trigger can be 34 | removed by invoking this action again with a Timeout value of zero. 35 | 36 | Triggers 37 | ======== 38 | 39 | The idle module defines trigger `resumed` by default. This trigger is emitted 40 | on the first user interaction after a timeout. Timeout triggers are defined 41 | using the `IdleTimeout` action. 42 | -------------------------------------------------------------------------------- /doc/sfwbar-idleinhibit.1: -------------------------------------------------------------------------------- 1 | .\" Man page generated from reStructuredText. 2 | . 3 | . 4 | .nr rst2man-indent-level 0 5 | . 6 | .de1 rstReportMargin 7 | \\$1 \\n[an-margin] 8 | level \\n[rst2man-indent-level] 9 | level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] 10 | - 11 | \\n[rst2man-indent0] 12 | \\n[rst2man-indent1] 13 | \\n[rst2man-indent2] 14 | .. 15 | .de1 INDENT 16 | .\" .rstReportMargin pre: 17 | . RS \\$1 18 | . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] 19 | . nr rst2man-indent-level +1 20 | .\" .rstReportMargin post: 21 | .. 22 | .de UNINDENT 23 | . RE 24 | .\" indent \\n[an-margin] 25 | .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] 26 | .nr rst2man-indent-level -1 27 | .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] 28 | .in \\n[rst2man-indent\\n[rst2man-indent-level]]u 29 | .. 30 | .TH "SFWBAR-IDLEINHIBIT" 1 "" "" 31 | .SH NAME 32 | sfwbar-idleinhibit \- Sfwbar IdleInhibitor module 33 | .sp 34 | Filename: idleinhibit.so 35 | .sp 36 | Requires: none 37 | .SH SYNOPSIS 38 | .sp 39 | The IdleInhibit module, allows attaching idle inhibitor to any widget in the 40 | taskbar. If an idle inhibitor is active on a visible widget, it will prevent 41 | the compositor to going into an idle state (i.e. blanking a screen, 42 | going into a suspend mode or activating a screensaver) 43 | .SH EXPRESSION FUNCTIONS 44 | .SS IdleInhibitState() 45 | .sp 46 | Query an idle inhibitor state on a calling widget. It return a string with 47 | possible values of \(dqOn\(dq, if an idle inhibitor is set on the widget or \(dqOff\(dq 48 | if it isn\(aqt. If the function is called from an expression which isn\(aqt attached 49 | to a widget, the returned value will be \(dqOff\(dq. 50 | .SH ACTIONS 51 | .SS SetIdleInhibitor Command 52 | .sp 53 | Set idle inhibitor state for a widget. The possible command values are: 54 | .INDENT 0.0 55 | .TP 56 | .B \(dqOn\(dq 57 | turn on an idle inhibitor 58 | .TP 59 | .B \(dqOff\(dq 60 | turn off an idle inhibitor 61 | .TP 62 | .B \(dqToggle\(dq 63 | toggle the state of an idle inhibitor 64 | .UNINDENT 65 | .SH TRIGGERS 66 | .sp 67 | The module defines one trigger \(dqIdleInhibitor\(dq which is emitted whenever the 68 | state of any idle inhibitor changes. 69 | .SH COPYRIGHT 70 | GPLv3+ 71 | .\" Generated by docutils manpage writer. 72 | . 73 | -------------------------------------------------------------------------------- /doc/sfwbar-idleinhibit.rst: -------------------------------------------------------------------------------- 1 | sfwbar-idleinhibit 2 | ################## 3 | 4 | ########################### 5 | Sfwbar IdleInhibitor module 6 | ########################### 7 | 8 | :Copyright: GPLv3+ 9 | :Manual section: 1 10 | 11 | Filename: idleinhibit.so 12 | 13 | Requires: none 14 | 15 | SYNOPSIS 16 | ======== 17 | 18 | The IdleInhibit module, allows attaching idle inhibitor to any widget in the 19 | taskbar. If an idle inhibitor is active on a visible widget, it will prevent 20 | the compositor to going into an idle state (i.e. blanking a screen, 21 | going into a suspend mode or activating a screensaver) 22 | 23 | Expression Functions 24 | ==================== 25 | 26 | IdleInhibitState() 27 | ------------------------ 28 | 29 | Query an idle inhibitor state on a calling widget. It return a string with 30 | possible values of "On", if an idle inhibitor is set on the widget or "Off" 31 | if it isn't. If the function is called from an expression which isn't attached 32 | to a widget, the returned value will be "Off". 33 | 34 | Actions 35 | ======= 36 | 37 | SetIdleInhibitor Command 38 | ----------------------------- 39 | 40 | Set idle inhibitor state for a widget. The possible command values are: 41 | 42 | "On" 43 | turn on an idle inhibitor 44 | "Off" 45 | turn off an idle inhibitor 46 | "Toggle" 47 | toggle the state of an idle inhibitor 48 | 49 | Triggers 50 | ======== 51 | 52 | The module defines one trigger "IdleInhibitor" which is emitted whenever the 53 | state of any idle inhibitor changes. 54 | -------------------------------------------------------------------------------- /doc/sfwbar-mpd.rst: -------------------------------------------------------------------------------- 1 | sfwbar-mpd 2 | ############ 3 | 4 | ################################# 5 | Sfwbar Music Player Daemon module 6 | ################################# 7 | 8 | :Copyright: GPLv3+ 9 | :Manual section: 1 10 | 11 | Filename: mpd.so 12 | 13 | Requires: libmpdclient 14 | 15 | SYNOPSIS 16 | ======== 17 | 18 | The Music Player Daemon module provides an interface to control an MPD server. 19 | 20 | Expression Functions 21 | ==================== 22 | 23 | Mpd(Query) 24 | ------------------------ 25 | 26 | Function Mpd queries the state of the MPD server. The function returns a string. 27 | the following queries are supported: 28 | 29 | "title" 30 | The title of current song. 31 | "track" 32 | Track number of the current song. 33 | "artist" 34 | Artist of the current song. 35 | "album" 36 | Album of the current song. 37 | "genre" 38 | Genre of the current song. 39 | "volume" 40 | Current playback volume. 41 | "repeat" 42 | Repeat flag of the current playlist: "1"/"0". 43 | "random" 44 | Random flag of the current playlist: "1"/"0". 45 | "queue_len" 46 | Length of the current playlist. 47 | "queue_pos" 48 | Number of the current song in the playlist. 49 | "elapsed" 50 | Elapsed time since the beginning of the song. 51 | "length" 52 | Length of the current song. 53 | "rate" 54 | Sample rate of the current song (in kbps). 55 | "state" 56 | State of the player: "play","pause","stop","unknown". 57 | 58 | Actions 59 | ======= 60 | 61 | MpdSetPassword "Password" 62 | ------------------------- 63 | 64 | Specify a password used to connect to the MPD server. 65 | 66 | MpdCommand "Command" 67 | -------------------- 68 | 69 | Send a command to the MPD server. The supported commands are: 70 | 71 | "play" 72 | Play the current song. 73 | "pause" 74 | Pause playback. 75 | "stop" 76 | Stop playback. 77 | "prev" 78 | Switch to the previous song in the playlist. 79 | "next" 80 | Switch to the next song in the playlist. 81 | 82 | Triggers 83 | ======== 84 | 85 | The module defines two triggers: 86 | 87 | "mpd" 88 | Emitted whenever the state of the MPD server changes. 89 | "mpd-progress" 90 | Emitted every second while player is in "play" state. 91 | -------------------------------------------------------------------------------- /doc/sfwbar-network.rst: -------------------------------------------------------------------------------- 1 | sfwbar-network 2 | ############## 3 | 4 | ##################### 5 | Sfwbar Network module 6 | ##################### 7 | 8 | :Copyright: GPLv3+ 9 | :Manual section: 1 10 | 11 | Filename: network.so 12 | 13 | Requires: none 14 | 15 | SYNOPSIS 16 | ======== 17 | 18 | The network module tracks the state of the current network connection. 19 | 20 | Expression Functions 21 | ==================== 22 | 23 | NetInfo(Query[,Interface]) 24 | -------------------------- 25 | 26 | Function NetInfo queries the parameter of the connection on the network 27 | interface specified. If Interface is not specified, NetInfo will query the 28 | interface of the default gateway (if one exists). The queries supported are: 29 | 30 | "ip" 31 | IP address of the interface. 32 | "mask" 33 | Net mask of the interface. 34 | "cidr" 35 | Net mask in the CIDR notation. 36 | "gateway" 37 | The default gateway (not necessarily associated with the interface). 38 | "ip6" 39 | IPv6 IP address of the interface. 40 | "mask6" 41 | IPv6 netmask of the interfce. 42 | "gateway6" 43 | The default IPv6 gateway. 44 | "essid" 45 | ESSID of the wireless connection (if applicable for the interface). 46 | 47 | NetInfo returns a string value. 48 | 49 | NetStat(Query[,Interface]) 50 | -------------------------- 51 | 52 | Function NetStat queries statistics of the interface. If the interface 53 | isn't specified, it will be applied to the interface of the default gateway. 54 | The queries supported are: 55 | 56 | "rxrate" 57 | Receive data rate on the interface (in bps). 58 | "txrate" 59 | Transmit data rate on the interface (in bps). 60 | "signal" 61 | Signal strength of the wifi connection (if applicable). 62 | 63 | NetState returns a numeric value. 64 | 65 | 66 | Actions 67 | ======= 68 | None 69 | 70 | Triggers 71 | ======== 72 | The module defines one trigger "network" which is emitted whenever the interface 73 | data is changes (i.e. ip, netmask, default gateway, wifi essid). 74 | -------------------------------------------------------------------------------- /doc/sfwbar-xkbmap.1: -------------------------------------------------------------------------------- 1 | .\" Man page generated from reStructuredText. 2 | . 3 | . 4 | .nr rst2man-indent-level 0 5 | . 6 | .de1 rstReportMargin 7 | \\$1 \\n[an-margin] 8 | level \\n[rst2man-indent-level] 9 | level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] 10 | - 11 | \\n[rst2man-indent0] 12 | \\n[rst2man-indent1] 13 | \\n[rst2man-indent2] 14 | .. 15 | .de1 INDENT 16 | .\" .rstReportMargin pre: 17 | . RS \\$1 18 | . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] 19 | . nr rst2man-indent-level +1 20 | .\" .rstReportMargin post: 21 | .. 22 | .de UNINDENT 23 | . RE 24 | .\" indent \\n[an-margin] 25 | .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] 26 | .nr rst2man-indent-level -1 27 | .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] 28 | .in \\n[rst2man-indent\\n[rst2man-indent-level]]u 29 | .. 30 | .TH "SFWBAR-XKBMAP" 1 "" "" "" 31 | .SH NAME 32 | sfwbar-xkbmap \- Sfwbar xkbcommon layout module 33 | .sp 34 | Filename: xkbmap.so 35 | .sp 36 | Requires: libxkbregistry 37 | .SH SYNOPSIS 38 | .sp 39 | The XkbMap module provides an interface to convert between keyboard layout 40 | types. 41 | .SH EXPRESSION FUNCTIONS 42 | .SS XkbMap(Name,SourceType,DestType) 43 | .sp 44 | Function XkbMap converts between various name types for an XkbLayout. The 45 | function converts layout name Name from SourceType to DestType, the supported 46 | types are: \(dqdescription\(dq,\(dqname\(dq,\(dqvariant\(dq and \(dqbrief\(dq. 47 | .SH ACTIONS 48 | .sp 49 | None 50 | .SH TRIGGERS 51 | .sp 52 | None 53 | .SH COPYRIGHT 54 | GPLv3+ 55 | .\" Generated by docutils manpage writer. 56 | . 57 | -------------------------------------------------------------------------------- /doc/sfwbar-xkbmap.rst: -------------------------------------------------------------------------------- 1 | sfwbar-xkbmap 2 | ############# 3 | 4 | ############################## 5 | Sfwbar xkbcommon layout module 6 | ############################## 7 | 8 | :Copyright: GPLv3+ 9 | :Manual section: 1 10 | 11 | Filename: xkbmap.so 12 | 13 | Requires: libxkbregistry 14 | 15 | SYNOPSIS 16 | ======== 17 | 18 | The XkbMap module provides an interface to convert between keyboard layout 19 | types. 20 | 21 | Expression Functions 22 | ==================== 23 | 24 | XkbMap(Name,SourceType,DestType) 25 | -------------------------------- 26 | 27 | Function XkbMap converts between various name types for an XkbLayout. The 28 | function converts layout name Name from SourceType to DestType, the supported 29 | types are: "description","name","variant" and "brief". 30 | 31 | Actions 32 | ======= 33 | 34 | None 35 | 36 | Triggers 37 | ======== 38 | 39 | None 40 | -------------------------------------------------------------------------------- /icons/misc/comp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 14 | 16 | 17 | 19 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /icons/misc/fforward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /icons/misc/lan.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 11 | 13 | 15 | 17 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /icons/misc/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /icons/misc/missing.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /icons/misc/music-player-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /icons/misc/music-player.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /icons/misc/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /icons/misc/rewind.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /icons/misc/stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /icons/misc/unlock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /icons/sfwbar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /icons/weather/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2017 Yr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /icons/weather/clearsky_day.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /icons/weather/clearsky_night.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /icons/weather/clearsky_polartwilight.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /icons/weather/cloudy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /icons/weather/fair_night.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /icons/weather/fog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /icons/weather/heavyrain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /icons/weather/heavyrainandthunder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /icons/weather/heavysleet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /icons/weather/heavysnow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /icons/weather/lightrain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /icons/weather/lightrainandthunder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /icons/weather/lightrainshowers_night.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /icons/weather/lightsleet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /icons/weather/lightsleetandthunder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /icons/weather/lightsnow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /icons/weather/lightsnowandthunder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /icons/weather/partlycloudy_night.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /icons/weather/rain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /icons/weather/rainandthunder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /icons/weather/sleet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /icons/weather/snow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /icons/weather/snowandthunder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /meson.h.meson: -------------------------------------------------------------------------------- 1 | 2 | #define GTK_LAYER_VER_MAJOR @glsh_major@ 3 | #define GTK_LAYER_VER_MINOR @glsh_minor@ 4 | #define GTK_LAYER_VER_MICRO @glsh_micro@ 5 | #define MODULE_DIR "@module_dir@" 6 | #define SYSTEM_CONF_DIR "@conf_dir@" 7 | #define LOCALE_DIR "@locale_dir@" 8 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('alsa',type:'feature',value:'auto',description:'ALSA module') 2 | option('appmenu',type:'feature',value:'enabled',description:'Application menu generator') 3 | option('bluez',type:'feature',value:'auto',description:'Bluez module') 4 | option('iwd',type:'feature',value:'auto',description:'IWD wifi module') 5 | option('nm',type:'feature',value:'auto',description:'Network Manager wifi module') 6 | option('ncenter',type:'feature',value:'auto',description:'Notification Center module') 7 | option('bsdctl',type:'feature',value:'disabled',description:'BSD sysctl module') 8 | option('idle',type:'feature',value:'auto',description:'Idle notification support') 9 | option('idleinhibit',type:'feature',value:'auto',description:'Idle inhibit protocol support') 10 | option('network',type:'feature',value:'auto',description:'Network module') 11 | option('pulse',type:'feature',value:'auto',description:'Pulse Audio module') 12 | option('pipewire',type:'feature',value:'auto',description:'Pipewire module') 13 | option('mpd',type:'feature',value:'auto',description:'Music Player Daemon module') 14 | option('xkb',type:'feature',value:'auto',description:'xkbcommon layout lookup') 15 | option('build-docs',type:'feature',value:'auto',description:'rebuild man pages from rst files') 16 | -------------------------------------------------------------------------------- /modules/idleinhibit.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2023- Sfwbar maintainers 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "module.h" 10 | #include "trigger.h" 11 | #include "wayland.h" 12 | #include "idle-inhibit-unstable-v1.h" 13 | #include "vm/vm.h" 14 | 15 | gint64 sfwbar_module_signature = 0x73f4d956a1; 16 | guint16 sfwbar_module_version = MODULE_API_VERSION; 17 | static struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager; 18 | 19 | static value_t idle_inhibit_state ( vm_t *vm, value_t p[], gint np ) 20 | { 21 | return value_new_string(g_strdup((vm->widget && g_object_get_data( 22 | G_OBJECT(vm->widget), "inhibitor"))? "on" : "off")); 23 | } 24 | 25 | static value_t idle_inhibitor_action ( vm_t *vm, value_t p[], gint np ) 26 | { 27 | struct wl_surface *surface; 28 | struct zwp_idle_inhibitor_v1 *inhibitor; 29 | gboolean inhibit; 30 | 31 | vm_param_check_np(vm, np, 1, "SetIdleInhibitor"); 32 | vm_param_check_string(vm, p, 0, "SetIdleInhibitor"); 33 | 34 | inhibitor = g_object_get_data(G_OBJECT(vm->widget), "inhibitor"); 35 | 36 | if(!g_ascii_strcasecmp(value_get_string(p[0]), "on")) 37 | inhibit = TRUE; 38 | else if(!g_ascii_strcasecmp(value_get_string(p[0]), "off")) 39 | inhibit = FALSE; 40 | else if(!g_ascii_strcasecmp(value_get_string(p[0]), "toggle")) 41 | inhibit = !inhibitor; 42 | else 43 | return value_na; 44 | 45 | if(inhibit && !inhibitor) 46 | { 47 | if( !(surface = gdk_wayland_window_get_wl_surface( 48 | gtk_widget_get_window(vm->widget))) ) 49 | return value_na; 50 | 51 | inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor( 52 | idle_inhibit_manager, surface ); 53 | g_object_set_data(G_OBJECT(vm->widget), "inhibitor", inhibitor); 54 | trigger_emit("idleinhibitor"); 55 | } 56 | else if( !inhibit && inhibitor ) 57 | { 58 | g_object_set_data(G_OBJECT(vm->widget), "inhibitor", NULL); 59 | zwp_idle_inhibitor_v1_destroy(inhibitor); 60 | trigger_emit("idleinhibitor"); 61 | } 62 | return value_na; 63 | } 64 | 65 | gboolean sfwbar_module_init ( void ) 66 | { 67 | vm_func_add("idleinhibitstate", idle_inhibit_state, FALSE); 68 | vm_func_add("setidleinhibitor", idle_inhibitor_action, TRUE); 69 | idle_inhibit_manager = wayland_iface_register( 70 | zwp_idle_inhibit_manager_v1_interface.name, 1, 1, 71 | &zwp_idle_inhibit_manager_v1_interface); 72 | return TRUE; 73 | } 74 | -------------------------------------------------------------------------------- /modules/xkbmap.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2023- Sfwbar maintainers 4 | */ 5 | 6 | #include 7 | #include 8 | #include "module.h" 9 | #include "vm/vm.h" 10 | 11 | gint64 sfwbar_module_signature = 0x73f4d956a1; 12 | guint16 sfwbar_module_version = MODULE_API_VERSION; 13 | static struct rxkb_context *ctx; 14 | 15 | static const gchar *xkb_get_value ( struct rxkb_layout *layout, gchar *type ) 16 | { 17 | if(!g_ascii_strcasecmp(type,"description")) 18 | return rxkb_layout_get_description(layout); 19 | if(!g_ascii_strcasecmp(type,"name")) 20 | return rxkb_layout_get_name(layout); 21 | if(!g_ascii_strcasecmp(type,"variant")) 22 | return rxkb_layout_get_variant(layout); 23 | if(!g_ascii_strcasecmp(type,"brief")) 24 | return rxkb_layout_get_brief(layout); 25 | return g_strdup_printf("XkbMap: Invalid type: %s",type); 26 | } 27 | 28 | static value_t xkb_map_expr_func ( vm_t *vm, value_t p[], gint np ) 29 | { 30 | struct rxkb_layout *layout; 31 | 32 | if(np!=3 || !value_is_string(p[0]) || !value_is_string(p[1]) || 33 | !value_is_string(p[2])) 34 | return value_new_string(g_strdup("XkbMap: missing parameter(s)")); 35 | 36 | for(layout=rxkb_layout_first(ctx); layout; layout=rxkb_layout_next(layout)) 37 | { 38 | if(!g_strcmp0(value_get_string(p[0]), 39 | xkb_get_value(layout, value_get_string(p[1])))) 40 | return value_new_string(g_strdup( 41 | xkb_get_value(layout, value_get_string(p[2])))); 42 | } 43 | 44 | return value_new_string(g_strdup_printf("XkbMap: Unknown layout: %s", 45 | value_get_string(p[0]))); 46 | } 47 | 48 | gboolean sfwbar_module_init ( void ) 49 | { 50 | if( !(ctx = rxkb_context_new (RXKB_CONTEXT_NO_DEFAULT_INCLUDES)) ) 51 | return FALSE; 52 | vm_func_add("xkbmap", xkb_map_expr_func, TRUE); 53 | rxkb_context_include_path_append_default(ctx); 54 | rxkb_context_parse_default_ruleset(ctx); 55 | return TRUE; 56 | } 57 | -------------------------------------------------------------------------------- /packaging/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Lev Babiev 2 | 3 | pkgname=sfwbar 4 | pkgver=1.0_beta10 5 | pkgrel=1 6 | 7 | pkgdesc='S* Floating Window taskBar' 8 | arch=('x86_64') 9 | url='https://github.com/LBCrion/sfwbar' 10 | license=('GPL3') 11 | depends=( 12 | 'wayland' 13 | 'gtk3' 14 | 'json-c' 15 | 'gtk-layer-shell' 16 | 'wayland-protocols' 17 | ) 18 | optdepends=( 19 | 'libpulse: pulse audio volume control', 20 | 'libmpdclient: music player daemon control', 21 | 'libxkbcommon: xkb layout conversion support' 22 | ) 23 | makedepends=( 24 | 'meson' 25 | ) 26 | 27 | source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz") 28 | 29 | sha256sums=('88d192940c8f4c74fbeab6f054fa9ec57b42f7053859317c9a0de9cf6995b2a3') 30 | 31 | build() { 32 | cd "$pkgname-$pkgver" 33 | meson --prefix=/usr \ 34 | --buildtype=plain \ 35 | build 36 | ninja -C build 37 | } 38 | 39 | package() { 40 | cd "$pkgname-$pkgver" 41 | DESTDIR="$pkgdir" ninja -C build install 42 | } 43 | -------------------------------------------------------------------------------- /packaging/freebsd/Makefile: -------------------------------------------------------------------------------- 1 | PORTNAME= sfwbar 2 | DISTVERSIONPREFIX= v 3 | DISTVERSION= 1.0_beta13 4 | CATEGORIES= x11 wayland 5 | 6 | MAINTAINER= tino.engel@mail.de 7 | COMMENT= Flexible taskbar application for wayland compositors 8 | WWW= https://github.com/LBCrion/sfwbar 9 | 10 | LICENSE= GPLv3 11 | LICENSE_FILE= ${WRKSRC}/LICENSE 12 | 13 | BUILD_DEPENDS= wayland-protocols>0:graphics/wayland-protocols 14 | LIB_DEPENDS= libgtk-layer-shell.so:x11-toolkits/gtk-layer-shell \ 15 | libwayland-client.so:graphics/wayland \ 16 | libjson-c.so:devel/json-c 17 | 18 | USES= gnome meson pkgconfig 19 | USE_GNOME= cairo gdkpixbuf2 gtk30 20 | 21 | USE_GITHUB= yes 22 | GH_ACCOUNT= LBCrion 23 | 24 | MESON_ARGS= -Dbsdctl=enabled -Dnetwork=enabled -Dbluez=enabled -Didleinhibit=enabled 25 | 26 | OPTIONS_DEFINE= MPD PULSEAUDIO XKB ALSA 27 | OPTIONS_DEFAULT= MPD PULSEAUDIO XKB ALSA 28 | OPTIONS_SUB= yes 29 | 30 | MPD_DESC= Music player daemon control 31 | MPD_LIB_DEPENDS= libmpdclient.so:audio/libmpdclient 32 | MPD_MESON_ENABLED= mpd 33 | 34 | PULSEAUDIO_DESC= Pulse audio volume control 35 | PULSEAUDIO_LIB_DEPENDS= libpulse.so:audio/pulseaudio 36 | PULSEAUDIO_MESON_ENABLED= pulse 37 | 38 | XKB_DESC= XkbCommon keyboard layout conversion support 39 | XKB_LIB_DEPENDS= libxkbregistry.so:x11/libxkbcommon 40 | XKB_MESON_ENABLED= xkb 41 | 42 | ALSA_DESC= ALSA audio volume control 43 | ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib 44 | ALSA_MESON_ENABLED= alsa 45 | 46 | SUB_FILES= pkg-message 47 | 48 | .include 49 | -------------------------------------------------------------------------------- /packaging/freebsd/distinfo: -------------------------------------------------------------------------------- 1 | TIMESTAMP = 1691478313 2 | SHA256 (LBCrion-sfwbar-v1.0_beta12_GH0.tar.gz) = 98dfdc9915d57c17588e71a8c50964891e8aa6fcda8077ef390924fe28445eda 3 | SIZE (LBCrion-sfwbar-v1.0_beta12_GH0.tar.gz) = 362373 4 | -------------------------------------------------------------------------------- /packaging/freebsd/files/pkg-message.in: -------------------------------------------------------------------------------- 1 | [ 2 | { type: install 3 | message: < 5 | 6 | typedef void (*AppInfoHandler)( const gchar * ); 7 | 8 | void app_info_init ( void ); 9 | void app_info_add_handlers ( AppInfoHandler add, AppInfoHandler del ); 10 | void app_info_remove_handlers ( AppInfoHandler add, AppInfoHandler del ); 11 | void app_icon_map_add ( gchar *appid, gchar *icon ); 12 | gchar *app_info_icon_lookup ( gchar *app_id, gboolean prefer_symbolic ); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/client.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLIENT_H__ 2 | #define __CLIENT_H__ 3 | 4 | #include 5 | #include "scanner.h" 6 | 7 | typedef struct _Client Client; 8 | struct _Client { 9 | ScanFile *file; 10 | GSocketConnection *scon; 11 | GSocketConnectable *addr; 12 | GSocketClient *sclient; 13 | GIOChannel *in,*out; 14 | void *data; 15 | gboolean (*connect) ( Client * ); 16 | GIOStatus (*respond) ( Client * ); 17 | GIOStatus (*consume) ( Client *, gsize *size ); 18 | }; 19 | 20 | void client_exec ( ScanFile *file ); 21 | void client_socket ( ScanFile *file ); 22 | void client_mpd ( ScanFile *file ); 23 | void client_attach ( Client *client ); 24 | gboolean client_socket_connect ( Client *client ); 25 | void client_send ( gchar *addr, gchar *command ); 26 | void client_mpd_command ( gchar *command ); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/gui/button.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2022- sfwbar maintainers 4 | */ 5 | 6 | #include "basewidget.h" 7 | #include "button.h" 8 | #include "scaleimage.h" 9 | 10 | G_DEFINE_TYPE_WITH_CODE (Button, button, BASE_WIDGET_TYPE, G_ADD_PRIVATE (Button)) 11 | 12 | static void button_update_value ( GtkWidget *self ) 13 | { 14 | ButtonPrivate *priv; 15 | 16 | g_return_if_fail(IS_BUTTON(self)); 17 | priv = button_get_instance_private(BUTTON(self)); 18 | 19 | scale_image_set_image(GTK_WIDGET(priv->image), base_widget_get_value(self), 20 | NULL); 21 | } 22 | 23 | static void button_class_init ( ButtonClass *kclass ) 24 | { 25 | BASE_WIDGET_CLASS(kclass)->update_value = button_update_value; 26 | } 27 | 28 | static void button_init ( Button *self ) 29 | { 30 | ButtonPrivate *priv; 31 | 32 | priv = button_get_instance_private(BUTTON(self)); 33 | 34 | priv->button = gtk_button_new(); 35 | priv->image = scale_image_new(); 36 | gtk_container_add(GTK_CONTAINER(priv->button), priv->image); 37 | gtk_container_add(GTK_CONTAINER(self), priv->button); 38 | } 39 | -------------------------------------------------------------------------------- /src/gui/button.h: -------------------------------------------------------------------------------- 1 | #ifndef __BUTTON_H__ 2 | #define __BUTTON_H__ 3 | 4 | #include "basewidget.h" 5 | 6 | #define BUTTON_TYPE (button_get_type()) 7 | #define BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), BUTTON_TYPE, Button)) 8 | #define BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), BUTTON_TYPE, ButtonClass)) 9 | #define IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), BUTTON_TYPE)) 10 | #define IS_BUTTONCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), BUTTON_TYPE)) 11 | 12 | typedef struct _Button Button; 13 | typedef struct _ButtonClass ButtonClass; 14 | 15 | struct _Button 16 | { 17 | BaseWidget item; 18 | }; 19 | 20 | struct _ButtonClass 21 | { 22 | BaseWidgetClass parent_class; 23 | }; 24 | 25 | typedef struct _ButtonPrivate ButtonPrivate; 26 | 27 | struct _ButtonPrivate 28 | { 29 | GtkWidget *button; 30 | GtkWidget *image; 31 | }; 32 | 33 | GType button_get_type ( void ); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/gui/cchart.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2022- sfwbar maintainers 4 | */ 5 | 6 | #include "cchart.h" 7 | #include "chart.h" 8 | 9 | G_DEFINE_TYPE_WITH_CODE (CChart, cchart, BASE_WIDGET_TYPE, 10 | G_ADD_PRIVATE (CChart)) 11 | 12 | static void cchart_update_value ( GtkWidget *self ) 13 | { 14 | CChartPrivate *priv; 15 | gchar *value; 16 | 17 | g_return_if_fail(IS_CCHART(self)); 18 | priv = cchart_get_instance_private(CCHART(self)); 19 | 20 | value = base_widget_get_value(self); 21 | 22 | if(!g_strrstr(value,"nan")) 23 | chart_update(priv->chart,g_ascii_strtod(value,NULL)); 24 | } 25 | 26 | static void cchart_class_init ( CChartClass *kclass ) 27 | { 28 | BASE_WIDGET_CLASS(kclass)->update_value = cchart_update_value; 29 | BASE_WIDGET_CLASS(kclass)->always_update = TRUE; 30 | } 31 | 32 | static void cchart_init ( CChart *self ) 33 | { 34 | CChartPrivate *priv; 35 | 36 | priv = cchart_get_instance_private(CCHART(self)); 37 | 38 | priv->chart = chart_new(); 39 | gtk_container_add(GTK_CONTAINER(self),priv->chart); 40 | } 41 | -------------------------------------------------------------------------------- /src/gui/cchart.h: -------------------------------------------------------------------------------- 1 | #ifndef __CCHART_H__ 2 | #define __CCHART_H__ 3 | 4 | #include "basewidget.h" 5 | 6 | #define CCHART_TYPE (cchart_get_type()) 7 | #define CCHART(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CCHART_TYPE, CChart)) 8 | #define CCHART_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CCHART_TYPE, CChartClass)) 9 | #define IS_CCHART(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CCHART_TYPE)) 10 | #define IS_CCHARTCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CCHART_TYPE)) 11 | 12 | typedef struct _CChart CChart; 13 | typedef struct _CChartClass CChartClass; 14 | 15 | struct _CChart 16 | { 17 | BaseWidget item; 18 | }; 19 | 20 | struct _CChartClass 21 | { 22 | BaseWidgetClass parent_class; 23 | }; 24 | 25 | typedef struct _CChartPrivate CChartPrivate; 26 | 27 | struct _CChartPrivate 28 | { 29 | GtkWidget *chart; 30 | }; 31 | 32 | GType cchart_get_type ( void ); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/gui/chart.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHART_H__ 2 | #define __CHART_H__ 3 | 4 | #include 5 | 6 | #define CHART_TYPE (chart_get_type()) 7 | #define CHART(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHART_TYPE, Chart)) 8 | #define CHART_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHART_TYPE, ChartClass)) 9 | #define IS_CHART(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHART_TYPE)) 10 | #define IS_CHART_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHART_TYPE)) 11 | 12 | typedef struct _Chart Chart; 13 | typedef struct _ChartClass ChartClass; 14 | 15 | struct _Chart 16 | { 17 | GtkBox parent_class; 18 | }; 19 | 20 | struct _ChartClass 21 | { 22 | GtkBoxClass parent_class; 23 | }; 24 | 25 | typedef struct _ChartPrivate ChartPrivate; 26 | 27 | struct _ChartPrivate 28 | { 29 | GQueue *data; 30 | GtkWidget *chart; 31 | }; 32 | 33 | GType chart_get_type ( void ); 34 | 35 | GtkWidget *chart_new( void ); 36 | int chart_update ( GtkWidget *widget, gdouble n ); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/gui/css.h: -------------------------------------------------------------------------------- 1 | #ifndef __CSS_H__ 2 | #define __CSS_H__ 3 | 4 | #include 5 | 6 | void css_init ( gchar * ); 7 | void css_file_load ( gchar * ); 8 | GtkCssProvider *css_widget_apply ( GtkWidget *widget, gchar *css ); 9 | void css_widget_cascade ( GtkWidget *widget, gpointer data ); 10 | void css_add_class ( GtkWidget *widget, gchar *css_class ); 11 | void css_remove_class ( GtkWidget *widget, gchar *css_class ); 12 | void css_set_class ( GtkWidget *widget, gchar *css_class, gboolean state ); 13 | gchar *css_legacy_preprocess ( gchar *css_string, gchar *fname ); 14 | 15 | void widget_set_css ( GtkWidget *, gpointer ); 16 | void widget_parse_css ( GtkWidget *widget, gchar *css ); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/gui/flowgrid.h: -------------------------------------------------------------------------------- 1 | #ifndef __FLOWGRID_H__ 2 | #define __FLOWGRID_H__ 3 | 4 | #include 5 | #include "flowitem.h" 6 | 7 | #define FLOW_GRID_TYPE (flow_grid_get_type()) 8 | #define FLOW_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), FLOW_GRID_TYPE, FlowGrid)) 9 | #define FLOW_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), FLOW_GRID_TYPE, FlowGridClass)) 10 | #define IS_FLOW_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), FLOW_GRID_TYPE)) 11 | #define IS_FLOW_GRIDCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), FLOW_GRID_TYPE)) 12 | #define FLOW_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), FLOW_GRID_TYPE, FlowGridClass)) 13 | 14 | enum { 15 | /* drag_dest_add_(image|text|uri)_targets sets info to 0 */ 16 | SFWB_DND_TARGET_GENERIC_GTK_API, 17 | SFWB_DND_TARGET_FLOW_ITEM 18 | }; 19 | 20 | enum { 21 | FLOW_GRID_AXIS_ROWS = 1, 22 | FLOW_GRID_AXIS_COLS, 23 | }; 24 | 25 | typedef struct _FlowGrid FlowGrid; 26 | typedef struct _FlowGridClass FlowGridClass; 27 | 28 | struct _FlowGrid 29 | { 30 | BaseWidget item; 31 | }; 32 | 33 | struct _FlowGridClass 34 | { 35 | BaseWidgetClass parent_class; 36 | 37 | gboolean limit; 38 | }; 39 | 40 | typedef struct _FlowGridPrivate FlowGridPrivate; 41 | 42 | struct _FlowGridPrivate 43 | { 44 | gint cols,rows; 45 | gint primary_axis; 46 | gboolean icons, labels, tooltips; 47 | gint title_width; 48 | gboolean invalid; 49 | gboolean sort; 50 | GList *children; 51 | gint (*comp)( GtkWidget *, GtkWidget *, GtkWidget * ); 52 | GtkTargetEntry *dnd_target; 53 | GtkWidget *parent; 54 | GtkGrid *grid; 55 | }; 56 | 57 | GType flow_grid_get_type ( void ); 58 | 59 | void flow_grid_add_child ( GtkWidget *self, GtkWidget *child ); 60 | gboolean flow_grid_update ( GtkWidget *self ); 61 | void flow_grid_invalidate ( GtkWidget *self ); 62 | void flow_grid_delete_child ( GtkWidget *, void *parent ); 63 | GList *flow_grid_get_children ( GtkWidget *self ); 64 | guint flow_grid_n_children ( GtkWidget *self ); 65 | gpointer flow_grid_find_child ( GtkWidget *, gconstpointer parent ); 66 | void flow_grid_child_dnd_enable ( GtkWidget *, GtkWidget *, GtkWidget *); 67 | GtkWidget *flow_grid_get_parent ( GtkWidget *self ); 68 | void flow_grid_set_parent ( GtkWidget *self, GtkWidget *parent ); 69 | void flow_grid_set_dnd_target ( GtkWidget *self, GtkTargetEntry *target ); 70 | GtkTargetEntry *flow_grid_get_dnd_target ( GtkWidget *self ); 71 | void flow_grid_children_order ( GtkWidget *self, GtkWidget *ref, 72 | GtkWidget *child, gboolean after ); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/gui/flowitem.h: -------------------------------------------------------------------------------- 1 | #ifndef __FLOWITEM_H__ 2 | #define __FLOWITEM_H__ 3 | 4 | #include 5 | #include "basewidget.h" 6 | 7 | #define FLOW_ITEM_TYPE (flow_item_get_type()) 8 | #define FLOW_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), FLOW_ITEM_TYPE, FlowItemClass)) 9 | #define FLOW_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), FLOW_ITEM_TYPE, FlowItem)) 10 | #define IS_FLOW_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), FLOW_ITEM_TYPE)) 11 | #define IS_FLOW_TEMCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), FLOW_ITEM_TYPE)) 12 | #define FLOW_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), FLOW_ITEM_TYPE, FlowItemClass)) 13 | 14 | typedef struct _FlowItem FlowItem; 15 | typedef struct _FlowItemClass FlowItemClass; 16 | 17 | struct _FlowItem 18 | { 19 | BaseWidget widget; 20 | }; 21 | 22 | struct _FlowItemClass 23 | { 24 | BaseWidgetClass parent_class; 25 | 26 | void (*update) ( GtkWidget *self ); 27 | void (*decorate) (GtkWidget *, gboolean, gboolean); 28 | void (*set_title_width) (GtkWidget *, gint); 29 | void (*invalidate) ( GtkWidget *self ); 30 | void* (*get_source) ( GtkWidget *self ); 31 | gint (*compare) (GtkWidget *, GtkWidget *, GtkWidget *); 32 | void (*dnd_dest) ( GtkWidget *self, GtkWidget *src, gint x, gint y ); 33 | GCompareFunc comp_source; 34 | }; 35 | 36 | typedef struct _FlowItemPrivate FlowItemPrivate; 37 | 38 | struct _FlowItemPrivate 39 | { 40 | gboolean active; 41 | GtkWidget *parent; 42 | }; 43 | 44 | GType flow_item_get_type ( void ); 45 | 46 | void flow_item_update ( GtkWidget *self ); 47 | void flow_item_invalidate ( GtkWidget *self ); 48 | void *flow_item_get_source ( GtkWidget *self ); 49 | void flow_item_set_parent ( GtkWidget *self, GtkWidget *parent ); 50 | void flow_item_set_active ( GtkWidget *self, gboolean ); 51 | GtkWidget *flow_item_get_parent ( GtkWidget *self ); 52 | gboolean flow_item_get_active ( GtkWidget *self ); 53 | gint flow_item_compare ( GtkWidget *p1, GtkWidget *p2, GtkWidget *parent ); 54 | void flow_item_dnd_dest ( GtkWidget *self, GtkWidget *src, gint x, gint y ); 55 | gint flow_item_check_source ( GtkWidget *self, gconstpointer source ); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/gui/grid.h: -------------------------------------------------------------------------------- 1 | #ifndef __GRID_H__ 2 | #define __GRID_H__ 3 | 4 | #include "basewidget.h" 5 | 6 | #define GRID_TYPE (grid_get_type()) 7 | #define GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GRID_TYPE, Grid)) 8 | #define GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GRID_TYPE, GridClass)) 9 | #define IS_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GRID_TYPE)) 10 | #define IS_GRIDCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GRID_TYPE)) 11 | 12 | typedef struct _Grid Grid; 13 | typedef struct _GridClass GridClass; 14 | 15 | struct _Grid 16 | { 17 | BaseWidget item; 18 | }; 19 | 20 | struct _GridClass 21 | { 22 | BaseWidgetClass parent_class; 23 | }; 24 | 25 | typedef struct _GridPrivate GridPrivate; 26 | 27 | struct _GridPrivate 28 | { 29 | GtkWidget *grid; 30 | GList *last; 31 | GList *children; 32 | gint dir; 33 | }; 34 | 35 | GType grid_get_type ( void ); 36 | 37 | GtkWidget *grid_new(); 38 | gboolean grid_attach ( GtkWidget *self, GtkWidget *child ); 39 | void grid_detach( GtkWidget *child, GtkWidget *self ); 40 | void grid_mirror_child ( GtkWidget *self, GtkWidget *child ); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/gui/image.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2022- sfwbar maintainers 4 | */ 5 | 6 | #include "basewidget.h" 7 | #include "image.h" 8 | #include "scaleimage.h" 9 | 10 | G_DEFINE_TYPE_WITH_CODE (Image, image, BASE_WIDGET_TYPE, G_ADD_PRIVATE (Image)) 11 | 12 | static void image_update_value ( GtkWidget *self ) 13 | { 14 | ImagePrivate *priv; 15 | 16 | g_return_if_fail(IS_IMAGE(self)); 17 | priv = image_get_instance_private(IMAGE(self)); 18 | 19 | scale_image_set_image(GTK_WIDGET(priv->image), 20 | base_widget_get_value(self),NULL); 21 | } 22 | 23 | static void image_class_init ( ImageClass *kclass ) 24 | { 25 | BASE_WIDGET_CLASS(kclass)->update_value = image_update_value; 26 | } 27 | 28 | static void image_init ( Image *self ) 29 | { 30 | ImagePrivate *priv; 31 | 32 | priv = image_get_instance_private(IMAGE(self)); 33 | 34 | priv->image = scale_image_new(); 35 | gtk_container_add(GTK_CONTAINER(self),priv->image); 36 | } 37 | -------------------------------------------------------------------------------- /src/gui/image.h: -------------------------------------------------------------------------------- 1 | #ifndef __IMAGE_H__ 2 | #define __IMAGE_H__ 3 | 4 | #include "basewidget.h" 5 | 6 | #define IMAGE_TYPE (image_get_type()) 7 | #define IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), IMAGE_TYPE, Image)) 8 | #define IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), IMAGE_TYPE, ImageClass)) 9 | #define IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), IMAGE_TYPE)) 10 | #define IS_IMAGECLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), IMAGE_TYPE)) 11 | 12 | typedef struct _Image Image; 13 | typedef struct _ImageClass ImageClass; 14 | 15 | struct _Image 16 | { 17 | BaseWidget item; 18 | }; 19 | 20 | struct _ImageClass 21 | { 22 | BaseWidgetClass parent_class; 23 | }; 24 | 25 | typedef struct _ImagePrivate ImagePrivate; 26 | 27 | struct _ImagePrivate 28 | { 29 | GtkWidget *image; 30 | }; 31 | 32 | GType image_get_type ( void ); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/gui/label.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2022- sfwbar maintainers 4 | */ 5 | 6 | #include "basewidget.h" 7 | #include "label.h" 8 | 9 | G_DEFINE_TYPE_WITH_CODE (Label, label, BASE_WIDGET_TYPE, G_ADD_PRIVATE (Label)) 10 | 11 | static void label_update_value ( GtkWidget *self ) 12 | { 13 | LabelPrivate *priv; 14 | gchar *value; 15 | 16 | g_return_if_fail(IS_LABEL(self)); 17 | priv = label_get_instance_private(LABEL(self)); 18 | 19 | value = base_widget_get_value(self); 20 | if(value && pango_parse_markup(value, -1, 0, NULL, NULL, NULL, NULL)) 21 | gtk_label_set_markup(GTK_LABEL(priv->label), value); 22 | else 23 | gtk_label_set_text(GTK_LABEL(priv->label), value); 24 | } 25 | 26 | static void label_class_init ( LabelClass *kclass ) 27 | { 28 | BASE_WIDGET_CLASS(kclass)->update_value = label_update_value; 29 | } 30 | 31 | static void label_init ( Label *self ) 32 | { 33 | LabelPrivate *priv; 34 | 35 | priv = label_get_instance_private(LABEL(self)); 36 | 37 | priv->label = gtk_label_new(""); 38 | gtk_label_set_ellipsize(GTK_LABEL(priv->label), PANGO_ELLIPSIZE_END); 39 | gtk_label_set_line_wrap(GTK_LABEL(priv->label), TRUE); 40 | gtk_label_set_line_wrap_mode(GTK_LABEL(priv->label), PANGO_WRAP_WORD_CHAR); 41 | gtk_container_add(GTK_CONTAINER(self), priv->label); 42 | } 43 | -------------------------------------------------------------------------------- /src/gui/label.h: -------------------------------------------------------------------------------- 1 | #ifndef __LABEL_H__ 2 | #define __LABEL_H__ 3 | 4 | #include "basewidget.h" 5 | 6 | #define LABEL_TYPE (label_get_type()) 7 | #define LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LABEL_TYPE, Label)) 8 | #define LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), LABEL_TYPE, LabelClass)) 9 | #define IS_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), LABEL_TYPE)) 10 | #define IS_LABELCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LABEL_TYPE)) 11 | 12 | typedef struct _Label Label; 13 | typedef struct _LabelClass LabelClass; 14 | 15 | struct _Label 16 | { 17 | BaseWidget item; 18 | }; 19 | 20 | struct _LabelClass 21 | { 22 | BaseWidgetClass parent_class; 23 | }; 24 | 25 | typedef struct _LabelPrivate LabelPrivate; 26 | 27 | struct _LabelPrivate 28 | { 29 | GtkWidget *label; 30 | }; 31 | 32 | GType label_get_type ( void ); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/gui/menu.h: -------------------------------------------------------------------------------- 1 | #ifndef __MENU_H__ 2 | #define __MENU_H__ 3 | 4 | #include 5 | 6 | GtkWidget *menu_from_name ( gchar *name ); 7 | GtkWidget *menu_new ( gchar *name ); 8 | void menu_remove ( gchar *name ); 9 | void menu_item_remove ( gchar *id ); 10 | void menu_popup ( GtkWidget *, GtkWidget *, GdkEvent *, gpointer, guint16 * ); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/gui/menuitem.h: -------------------------------------------------------------------------------- 1 | #ifndef __MENUITEM_H__ 2 | #define __MENUITEM_H__ 3 | 4 | #include 5 | #include 6 | #include "vm/expr.h" 7 | 8 | typedef struct _MenuItemPrivate { 9 | gchar *id; 10 | gint sort_index; 11 | guint16 flags; 12 | gchar *desktop_file; 13 | GtkWidget *icon; 14 | GtkWidget *label; 15 | GtkWidget *box; 16 | GtkWidget *menu; 17 | GBytes *action; 18 | expr_cache_t *label_expr; 19 | expr_cache_t *tooltip_expr; 20 | } MenuItemPrivate; 21 | 22 | enum { 23 | MI_LABEL = 1, 24 | MI_ICON = 2, 25 | MI_TOOLTIP = 4, 26 | MI_ACTION = 8 27 | }; 28 | 29 | void menu_item_init( GtkWidget *self ); 30 | GtkWidget *menu_item_get ( gchar *id, gboolean create ); 31 | void menu_item_update_from_desktop ( GtkWidget *self, const gchar *desktop_id); 32 | void menu_item_update_from_app ( GtkWidget *self, GDesktopAppInfo *app); 33 | void menu_item_set_id ( GtkWidget *self, gchar *id ); 34 | gchar *menu_item_get_id ( GtkWidget *self ); 35 | void menu_item_set_label ( GtkWidget *self, const gchar *label ); 36 | void menu_item_set_label_expr ( GtkWidget *self, GBytes *code ); 37 | void menu_item_set_icon ( GtkWidget *self, const gchar *icon ); 38 | void menu_item_set_action ( GtkWidget *self, GBytes *action ); 39 | void menu_item_set_tooltip ( GtkWidget *self, GBytes *tooltip ); 40 | void menu_item_set_sort_index ( GtkWidget *self, gint index ); 41 | gint menu_item_get_sort_index ( GtkWidget *self ); 42 | void menu_item_set_submenu ( GtkWidget *self, gchar *subname ); 43 | gint menu_item_compare ( GtkWidget *i1, GtkWidget *i2 ); 44 | void menu_item_label_update ( GtkWidget *self ); 45 | void menu_item_insert ( GtkWidget *menu, GtkWidget *item ); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/gui/monitor.h: -------------------------------------------------------------------------------- 1 | #ifndef __OUTPUT_H__ 2 | #define __OUTPUT_H__ 3 | 4 | #include 5 | 6 | GdkMonitor *monitor_from_widget ( GtkWidget *self ); 7 | gboolean xdg_output_check ( void ); 8 | GdkMonitor *monitor_default_get ( void ); 9 | gchar *monitor_get_name ( GdkMonitor *monitor ); 10 | void monitor_init ( gchar * ); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/gui/pager.h: -------------------------------------------------------------------------------- 1 | #ifndef __PAGER_H__ 2 | #define __PAGER_H__ 3 | 4 | #include "flowgrid.h" 5 | #include "workspace.h" 6 | 7 | #define PAGER_TYPE (pager_get_type()) 8 | #define PAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PAGER_TYPE, Pager)) 9 | #define PAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PAGER_TYPE, PagerClass)) 10 | #define IS_PAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PAGER_TYPE)) 11 | #define IS_PAGERCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PAGER_TYPE)) 12 | 13 | typedef struct _Pager Pager; 14 | typedef struct _PagerClass PagerClass; 15 | typedef struct _PagerPrivate PagerPrivate; 16 | 17 | struct _Pager 18 | { 19 | FlowGrid item; 20 | }; 21 | 22 | struct _PagerClass 23 | { 24 | FlowGridClass parent_class; 25 | }; 26 | 27 | struct _PagerPrivate 28 | { 29 | GPtrArray *pins; 30 | guint timer_h; 31 | gboolean preview; 32 | }; 33 | 34 | GType pager_get_type ( void ); 35 | 36 | void pager_invalidate_all ( workspace_t *ws ); 37 | void pager_add_pins ( GtkWidget *self, GPtrArray *pins ); 38 | gboolean pager_check_pins ( GtkWidget *self, gchar *pin ); 39 | void pager_item_add ( workspace_t *ws ); 40 | void pager_item_delete ( workspace_t *ws ); 41 | void pager_update_all ( void ); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/gui/pageritem.h: -------------------------------------------------------------------------------- 1 | #ifndef __PAGERITEM_H__ 2 | #define __PAGERITEM_H__ 3 | 4 | #include "flowitem.h" 5 | #include "pager.h" 6 | 7 | #define PAGER_ITEM_TYPE (pager_item_get_type()) 8 | #define PAGER_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PAGER_ITEM_TYPE, PagerItem)) 9 | #define PAGER_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PAGER_ITEM_TYPE, PagerItemClass)) 10 | #define IS_PAGER_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PAGER_ITEM_TYPE)) 11 | #define IS_PAGER_ITEMCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PAGER_ITEM_TYPE)) 12 | 13 | typedef struct _PagerItem PagerItem; 14 | typedef struct _PagerItemClass PagerItemClass; 15 | 16 | struct _PagerItem 17 | { 18 | FlowItem item; 19 | }; 20 | 21 | struct _PagerItemClass 22 | { 23 | FlowItemClass parent_class; 24 | }; 25 | 26 | typedef struct _PagerItemPrivate PagerItemPrivate; 27 | 28 | struct _PagerItemPrivate 29 | { 30 | GtkWidget *button; 31 | GtkWidget *label; 32 | GtkWidget *pager; 33 | workspace_t *ws; 34 | gboolean invalid; 35 | }; 36 | 37 | GType pager_item_get_type ( void ); 38 | 39 | void pager_item_new( workspace_t *ws, GtkWidget *pager ); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/gui/popup.h: -------------------------------------------------------------------------------- 1 | #ifndef __POPUP_H__ 2 | #define __POPUP_H__ 3 | 4 | GtkWidget *popup_new ( gchar *name ); 5 | GtkWidget *popup_from_name ( gchar *name ); 6 | void popup_trigger ( GtkWidget *parent, gchar *name, GdkEvent *ev ); 7 | void popup_show ( GtkWidget *parent, GtkWidget *popup, GdkSeat *seat ); 8 | void popup_get_gravity ( GtkWidget *widget, GdkGravity *, GdkGravity * ); 9 | void popup_set_autoclose ( GtkWidget *win, gboolean autoclose ); 10 | void popup_popdown_autoclose ( void ); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/gui/scale.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2022- sfwbar maintainers 4 | */ 5 | 6 | #include "basewidget.h" 7 | #include "scale.h" 8 | 9 | G_DEFINE_TYPE_WITH_CODE (Scale, scale, BASE_WIDGET_TYPE, G_ADD_PRIVATE (Scale)) 10 | 11 | static void scale_update_value ( GtkWidget *self ) 12 | { 13 | ScalePrivate *priv; 14 | gchar *value; 15 | 16 | g_return_if_fail(IS_SCALE(self)); 17 | priv = scale_get_instance_private(SCALE(self)); 18 | 19 | value = base_widget_get_value(self); 20 | 21 | if(!g_strrstr(value,"nan")) 22 | gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(priv->scale), 23 | g_ascii_strtod(value,NULL)); 24 | } 25 | 26 | static void scale_style_updated ( GtkWidget *widget, GtkWidget *self ) 27 | { 28 | ScalePrivate *priv; 29 | gint dir; 30 | 31 | priv = scale_get_instance_private(SCALE(self)); 32 | gtk_widget_style_get(priv->scale,"direction",&dir,NULL); 33 | if(priv->dir == dir) 34 | return; 35 | priv->dir = dir; 36 | gtk_orientable_set_orientation(GTK_ORIENTABLE(priv->scale), 37 | (dir==GTK_POS_LEFT || dir==GTK_POS_RIGHT)? 38 | GTK_ORIENTATION_HORIZONTAL:GTK_ORIENTATION_VERTICAL); 39 | gtk_progress_bar_set_inverted(GTK_PROGRESS_BAR(priv->scale), 40 | ( priv->dir==GTK_POS_TOP || priv->dir==GTK_POS_LEFT )); 41 | } 42 | 43 | static void scale_class_init ( ScaleClass *kclass ) 44 | { 45 | BASE_WIDGET_CLASS(kclass)->update_value = scale_update_value; 46 | } 47 | 48 | static void scale_init ( Scale *self ) 49 | { 50 | ScalePrivate *priv; 51 | 52 | priv = scale_get_instance_private(SCALE(self)); 53 | 54 | priv->scale = gtk_progress_bar_new(); 55 | gtk_container_add(GTK_CONTAINER(self), priv->scale); 56 | g_signal_connect(G_OBJECT(priv->scale), "style_updated", 57 | (GCallback)scale_style_updated, self); 58 | } 59 | -------------------------------------------------------------------------------- /src/gui/scale.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCALE_H__ 2 | #define __SCALE_H__ 3 | 4 | #include "basewidget.h" 5 | 6 | #define SCALE_TYPE (scale_get_type()) 7 | #define SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SCALE_TYPE, Scale)) 8 | #define SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SCALE_TYPE, ScaleClass)) 9 | #define IS_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SCALE_TYPE)) 10 | #define IS_SCALECLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SCALE_TYPE)) 11 | 12 | typedef struct _Scale Scale; 13 | typedef struct _ScaleClass ScaleClass; 14 | 15 | struct _Scale 16 | { 17 | BaseWidget item; 18 | }; 19 | 20 | struct _ScaleClass 21 | { 22 | BaseWidgetClass parent_class; 23 | }; 24 | 25 | typedef struct _ScalePrivate ScalePrivate; 26 | 27 | struct _ScalePrivate 28 | { 29 | GtkWidget *scale; 30 | gint dir; 31 | }; 32 | 33 | GType scale_get_type ( void ); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/gui/scaleimage.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCALEIMAGE_H__ 2 | #define __SCALEIMAGE_H__ 3 | 4 | #include 5 | 6 | #define SCALE_IMAGE_TYPE (scale_image_get_type()) 7 | #define SCALE_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SCALE_IMAGE_TYPE, ScaleImage)) 8 | #define SCALE_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SCALE_IMAGE_TYPE, ScaleImageClass)) 9 | #define IS_SCALE_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SCALE_IMAGE_TYPE)) 10 | #define IS_SCALE_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SCALE_IMAGE_TYPE)) 11 | 12 | typedef struct _ScaleImage ScaleImage; 13 | typedef struct _ScaleImageClass ScaleImageClass; 14 | 15 | struct _ScaleImage 16 | { 17 | GtkImage parent_class; 18 | }; 19 | 20 | struct _ScaleImageClass 21 | { 22 | GtkImageClass parent_class; 23 | }; 24 | 25 | typedef struct _ScaleImagePrivate ScaleImagePrivate; 26 | 27 | struct _ScaleImagePrivate 28 | { 29 | gint ftype; 30 | gint width, height; 31 | gint radius, shadow_dx, shadow_dy; 32 | GdkRGBA *color; 33 | GdkRGBA *shadow_color; 34 | gboolean shadow_clip; 35 | gboolean fallback; 36 | gboolean symbolic; 37 | gboolean symbolic_pref; 38 | gchar *file; 39 | gchar *extra; 40 | gchar *fname; 41 | GtkIconTheme *theme; 42 | GdkPixbuf *pixbuf; 43 | cairo_surface_t *cs, *shadow; 44 | }; 45 | 46 | enum { 47 | SI_NONE, 48 | SI_ICON, 49 | SI_FILE, 50 | SI_BUFF, 51 | SI_DATA 52 | }; 53 | 54 | GType scale_image_get_type ( void ); 55 | gboolean scale_image_set_image ( GtkWidget *, const gchar *, gchar *); 56 | GtkWidget *scale_image_new(); 57 | int scale_image_update ( GtkWidget *widget ); 58 | gboolean scale_image_cache_insert ( gchar *name, GdkPixbuf *pb ); 59 | gboolean scale_image_cache_remove ( gchar *name ); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/gui/switcher.h: -------------------------------------------------------------------------------- 1 | #ifndef __SWITCHER_H__ 2 | #define __SWITCHER_H__ 3 | 4 | #include "basewidget.h" 5 | #include "flowgrid.h" 6 | 7 | #define SWITCHER_TYPE (switcher_get_type()) 8 | #define SWITCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SWITCHER_TYPE, Switcher)) 9 | #define SWITCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SWITCHER_TYPE, SwitcherClass)) 10 | #define IS_SWITCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SWITCHER_TYPE)) 11 | #define IS_SWITCHERCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SWITCHER_TYPE)) 12 | 13 | typedef struct _Switcher Switcher; 14 | typedef struct _SwitcherClass SwitcherClass; 15 | 16 | struct _Switcher 17 | { 18 | FlowGrid item; 19 | }; 20 | 21 | struct _SwitcherClass 22 | { 23 | FlowGridClass parent_class; 24 | }; 25 | 26 | typedef struct _SwitcherPrivate SwitcherPrivate; 27 | 28 | struct _SwitcherPrivate 29 | { 30 | GtkWidget *switcher; 31 | gint filter; 32 | }; 33 | 34 | GType switcher_get_type ( void ); 35 | void switcher_window_delete ( window_t *win ); 36 | 37 | GtkWidget *switcher_new(); 38 | gboolean switcher_state ( void ); 39 | gboolean switcher_event ( gpointer ); 40 | void switcher_invalidate ( window_t *win ); 41 | void switcher_window_init ( window_t *win); 42 | void switcher_populate ( void ); 43 | void switcher_set_filter ( GtkWidget *self, gint filter ); 44 | gint switcher_get_filter ( GtkWidget *self ); 45 | gboolean switcher_check ( GtkWidget *switcher, window_t *win ); 46 | gboolean switcher_is_focused ( gpointer uid ); 47 | void switcher_set_interval ( gint new_interval ); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/gui/switcheritem.h: -------------------------------------------------------------------------------- 1 | #ifndef __SWITCHERITEM_H__ 2 | #define __SWITCHERITEM_H__ 3 | 4 | #include "flowitem.h" 5 | #include "wintree.h" 6 | 7 | #define SWITCHER_ITEM_TYPE (switcher_item_get_type()) 8 | #define SWITCHER_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SWITCHER_ITEM_TYPE, SwitcherItem)) 9 | #define SWITCHER_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SWITCHER_ITEM_TYPE, SwitcherItemClass)) 10 | #define IS_SWITCHER_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SWITCHER_ITEM_TYPE)) 11 | #define IS_SWITCHER_ITEMCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SWITCHER_ITEM_TYPE)) 12 | 13 | typedef struct _SwitcherItem SwitcherItem; 14 | typedef struct _SwitcherItemClass SwitcherItemClass; 15 | 16 | struct _SwitcherItem 17 | { 18 | FlowItem item; 19 | }; 20 | 21 | struct _SwitcherItemClass 22 | { 23 | FlowItemClass parent_class; 24 | }; 25 | 26 | typedef struct _SwitcherItemPrivate SwitcherItemPrivate; 27 | 28 | struct _SwitcherItemPrivate 29 | { 30 | GtkWidget *icon; 31 | GtkWidget *label; 32 | GtkWidget *grid; 33 | GtkWidget *switcher; 34 | window_t *win; 35 | gboolean invalid; 36 | }; 37 | 38 | GType switcher_item_get_type ( void ); 39 | 40 | GtkWidget *switcher_item_new( window_t *win, GtkWidget *switcher ); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/gui/taskbar.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2020- sfwbar maintainers 4 | */ 5 | 6 | #include "flowgrid.h" 7 | #include "taskbaritem.h" 8 | #include "taskbarpopup.h" 9 | #include "taskbarpager.h" 10 | #include "taskbarshell.h" 11 | #include "taskbar.h" 12 | #include "wintree.h" 13 | #include "config/config.h" 14 | #include "vm/vm.h" 15 | 16 | G_DEFINE_TYPE_WITH_CODE (Taskbar, taskbar, FLOW_GRID_TYPE, 17 | G_ADD_PRIVATE (Taskbar)) 18 | 19 | GtkWidget *taskbar_get_taskbar ( GtkWidget *shell, window_t *win, 20 | gboolean create ) 21 | { 22 | return shell; 23 | } 24 | 25 | static void taskbar_class_init ( TaskbarClass *kclass ) 26 | { 27 | BASE_WIDGET_CLASS(kclass)->action_exec = NULL; 28 | } 29 | 30 | static void taskbar_init ( Taskbar *self ) 31 | { 32 | GBytes *action; 33 | static guint8 data[sizeof(gpointer)+2]; 34 | gpointer fptr = vm_func_lookup("taskbaritemdefault"); 35 | 36 | data[0] = EXPR_OP_FUNCTION; 37 | memcpy(data+2, &fptr, sizeof(gpointer)); 38 | 39 | action = g_bytes_new_static(data, sizeof(gpointer)+2); 40 | base_widget_set_action(GTK_WIDGET(self), 1, 0, action); 41 | flow_grid_invalidate(GTK_WIDGET(self)); 42 | } 43 | 44 | GtkWidget *taskbar_new ( GtkWidget *parent ) 45 | { 46 | GtkWidget *self; 47 | TaskbarPrivate *priv; 48 | 49 | self = GTK_WIDGET(g_object_new(taskbar_get_type(), NULL)); 50 | priv = taskbar_get_instance_private(TASKBAR(self)); 51 | priv->parent = parent; 52 | 53 | return self; 54 | } 55 | 56 | GtkWidget *taskbar_get_parent ( GtkWidget *self ) 57 | { 58 | TaskbarPrivate *priv; 59 | 60 | g_return_val_if_fail(IS_TASKBAR(self), NULL); 61 | priv = taskbar_get_instance_private(TASKBAR(self)); 62 | 63 | return priv->parent; 64 | } 65 | -------------------------------------------------------------------------------- /src/gui/taskbar.h: -------------------------------------------------------------------------------- 1 | #ifndef __TASKBAR_H__ 2 | #define __TASKBAR_H__ 3 | 4 | #include "flowgrid.h" 5 | 6 | #define TASKBAR_TYPE (taskbar_get_type()) 7 | #define TASKBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TASKBAR_TYPE, Taskbar)) 8 | #define TASKBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TASKBAR_TYPE, TaskbarClass)) 9 | #define IS_TASKBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TASKBAR_TYPE)) 10 | #define IS_TASKBARCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TASKBAR_TYPE)) 11 | #define TASKBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TASKBAR_TYPE, TaskbarClass)) 12 | 13 | typedef struct _Taskbar Taskbar; 14 | typedef struct _TaskbarClass TaskbarClass; 15 | 16 | struct _Taskbar 17 | { 18 | FlowGrid item; 19 | }; 20 | 21 | struct _TaskbarClass 22 | { 23 | FlowGridClass parent_class; 24 | }; 25 | 26 | typedef struct _TaskbarPrivate TaskbarPrivate; 27 | 28 | struct _TaskbarPrivate 29 | { 30 | GtkWidget *parent; 31 | }; 32 | 33 | GType taskbar_get_type ( void ); 34 | 35 | GtkWidget *taskbar_new( GtkWidget *parent ); 36 | GtkWidget *taskbar_get_parent ( GtkWidget *self ); 37 | GtkWidget *taskbar_get_taskbar ( GtkWidget *, window_t *, gboolean ); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/gui/taskbaritem.h: -------------------------------------------------------------------------------- 1 | #ifndef __TASKBARITEM_H__ 2 | #define __TASKBARITEM_H__ 3 | 4 | #include "flowitem.h" 5 | 6 | #define TASKBAR_ITEM_TYPE (taskbar_item_get_type()) 7 | #define TASKBAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TASKBAR_ITEM_TYPE, TaskbarItem)) 8 | #define TASKBAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TASKBAR_ITEM_TYPE, TaskbarItemClass)) 9 | #define IS_TASKBAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TASKBAR_ITEM_TYPE)) 10 | #define IS_TASKBAR_ITEMCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TASKBAR_ITEM_TYPE)) 11 | 12 | typedef struct _TaskbarItem TaskbarItem; 13 | typedef struct _TaskbarItemClass TaskbarItemClass; 14 | 15 | struct _TaskbarItem 16 | { 17 | FlowItem item; 18 | }; 19 | 20 | struct _TaskbarItemClass 21 | { 22 | FlowItemClass parent_class; 23 | }; 24 | 25 | typedef struct _TaskbarItemPrivate TaskbarItemPrivate; 26 | 27 | struct _TaskbarItemPrivate 28 | { 29 | GtkWidget *icon; 30 | GtkWidget *label; 31 | GtkWidget *box; 32 | GtkWidget *taskbar; 33 | window_t *win; 34 | GBytes **actions; 35 | gboolean invalid; 36 | GdkModifierType saved_modifiers; 37 | }; 38 | 39 | GType taskbar_item_get_type ( void ); 40 | 41 | GtkWidget *taskbar_item_new( window_t *win, GtkWidget *taskbar ); 42 | void taskbar_item_set_image ( GtkWidget *icon, gchar *appid ); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/gui/taskbarpager.h: -------------------------------------------------------------------------------- 1 | #ifndef __TASKBARDESK_H__ 2 | #define __TASKBARDESK_H__ 3 | 4 | #include "flowitem.h" 5 | #include "workspace.h" 6 | #include "taskbar.h" 7 | 8 | #define TASKBAR_PAGER_TYPE (taskbar_pager_get_type()) 9 | #define TASKBAR_PAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TASKBAR_PAGER_TYPE, TaskbarPager)) 10 | #define TASKBAR_PAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TASKBAR_PAGER_TYPE, TaskbarPagerClass)) 11 | #define IS_TASKBAR_PAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TASKBAR_PAGER_TYPE)) 12 | #define IS_TASKBAR_PAGERCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TASKBAR_PAGER_TYPE)) 13 | 14 | typedef struct _TaskbarPager TaskbarPager; 15 | typedef struct _TaskbarPagerClass TaskbarPagerClass; 16 | 17 | struct _TaskbarPager 18 | { 19 | FlowItem item; 20 | }; 21 | 22 | struct _TaskbarPagerClass 23 | { 24 | FlowItemClass parent_class; 25 | }; 26 | 27 | typedef struct _TaskbarPagerPrivate TaskbarPagerPrivate; 28 | 29 | struct _TaskbarPagerPrivate 30 | { 31 | GtkWidget *button; 32 | GtkWidget *grid; 33 | GtkWidget *shell; 34 | GtkWidget *taskbar; 35 | workspace_t *ws; 36 | gboolean invalid; 37 | gboolean single; 38 | GList *holds; 39 | }; 40 | 41 | GType taskbar_pager_get_type ( void ); 42 | 43 | GtkWidget *taskbar_pager_new( workspace_t *ws, GtkWidget *taskbar ); 44 | GtkWidget *taskbar_pager_get_taskbar ( GtkWidget *, window_t *, gboolean ); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/gui/taskbarpopup.h: -------------------------------------------------------------------------------- 1 | #ifndef __TASKBARPOPUP_H__ 2 | #define __TASKBARPOPUP_H__ 3 | 4 | #include "flowitem.h" 5 | #include "taskbar.h" 6 | 7 | #define TASKBAR_POPUP_TYPE (taskbar_popup_get_type()) 8 | #define TASKBAR_POPUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TASKBAR_POPUP_TYPE, TaskbarPopup)) 9 | #define TASKBAR_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TASKBAR_POPUP_TYPE, TaskbarPopupClass)) 10 | #define IS_TASKBAR_POPUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TASKBAR_POPUP_TYPE)) 11 | #define IS_TASKBAR_POPUPCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TASKBAR_POPUP_TYPE)) 12 | 13 | typedef struct _TaskbarPopup TaskbarPopup; 14 | typedef struct _TaskbarPopupClass TaskbarPopupClass; 15 | 16 | struct _TaskbarPopup 17 | { 18 | FlowItem item; 19 | }; 20 | 21 | struct _TaskbarPopupClass 22 | { 23 | FlowItemClass parent_class; 24 | }; 25 | 26 | typedef struct _TaskbarPopupPrivate TaskbarPopupPrivate; 27 | 28 | struct _TaskbarPopupPrivate 29 | { 30 | GtkWidget *icon; 31 | GtkWidget *label; 32 | GtkWidget *button; 33 | GtkWidget *shell; 34 | GtkWidget *tgroup; 35 | GtkWidget *popover; 36 | gchar *appid; 37 | gboolean invalid; 38 | gboolean single; 39 | }; 40 | 41 | GType taskbar_popup_get_type ( void ); 42 | 43 | GtkWidget *taskbar_popup_new( const gchar *appid, GtkWidget *taskbar ); 44 | void taskbar_popup_pop_child ( GtkWidget *self, GtkWidget *child ); 45 | GtkWidget *taskbar_popup_get_taskbar ( GtkWidget *, window_t *, gboolean ); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/gui/taskbarshell.h: -------------------------------------------------------------------------------- 1 | #ifndef __TASKBARSHELL_H__ 2 | #define __TASKBARSHELL_H__ 3 | 4 | #include "taskbar.h" 5 | 6 | #define TASKBAR_SHELL_TYPE (taskbar_shell_get_type()) 7 | #define TASKBAR_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TASKBAR_SHELL_TYPE, TaskbarShell)) 8 | #define TASKBAR_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TASKBAR_SHELL_TYPE, TaskbarShellClass)) 9 | #define IS_TASKBAR_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TASKBAR_SHELL_TYPE)) 10 | #define IS_TASKBARSHELLCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TASKBAR_SHELL_TYPE)) 11 | 12 | typedef struct _TaskbarShell TaskbarShell; 13 | typedef struct _TaskbarShellClass TaskbarShellClass; 14 | 15 | struct _TaskbarShell 16 | { 17 | Taskbar item; 18 | }; 19 | 20 | struct _TaskbarShellClass 21 | { 22 | TaskbarClass parent_class; 23 | }; 24 | 25 | typedef struct _TaskbarShellPrivate TaskbarShellPrivate; 26 | 27 | struct _TaskbarShellPrivate 28 | { 29 | GtkWidget *(*get_taskbar)(GtkWidget *, window_t *, gboolean); 30 | gboolean icons, labels, sort, floating_filter; 31 | gint rows, cols, filter, title_width, primary_axis, api_id; 32 | gboolean tooltips; 33 | guint timer_h; 34 | GBytes *style; 35 | gchar *css; 36 | }; 37 | 38 | GType taskbar_shell_get_type ( void ); 39 | 40 | void taskbar_shell_init_child ( GtkWidget *self, GtkWidget *child ); 41 | void taskbar_shell_invalidate ( GtkWidget *self ); 42 | gboolean taskbar_shell_check_filter ( GtkWidget *self, window_t *win ); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/gui/tray.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2022- sfwbar maintainers 4 | */ 5 | 6 | #include "trayitem.h" 7 | #include "tray.h" 8 | 9 | G_DEFINE_TYPE_WITH_CODE (Tray, tray, FLOW_GRID_TYPE, G_ADD_PRIVATE (Tray)) 10 | 11 | static void tray_destroy ( GtkWidget *self ) 12 | { 13 | TrayPrivate *priv; 14 | 15 | g_return_if_fail(IS_TRAY(self)); 16 | priv = tray_get_instance_private(TRAY(self)); 17 | if(priv->timer_h) 18 | { 19 | g_source_remove(priv->timer_h); 20 | priv->timer_h = 0; 21 | } 22 | GTK_WIDGET_CLASS(tray_parent_class)->destroy(self); 23 | } 24 | 25 | static void tray_class_init ( TrayClass *kclass ) 26 | { 27 | GTK_WIDGET_CLASS(kclass)->destroy = tray_destroy; 28 | BASE_WIDGET_CLASS(kclass)->action_exec = NULL; 29 | sni_init(); 30 | } 31 | 32 | static void tray_invalidate_item ( sni_item_t *sni, GtkWidget *self ) 33 | { 34 | flow_item_invalidate(flow_grid_find_child(self, sni)); 35 | } 36 | 37 | static void tray_destroy_item ( sni_item_t *sni, GtkWidget *self ) 38 | { 39 | flow_grid_delete_child(self, sni); 40 | } 41 | 42 | static sni_listener_t tray_sni_listener = { 43 | .sni_new = (void (*)(sni_item_t *, void *))tray_item_new, 44 | .sni_invalidate = (void (*)(sni_item_t *, void *))tray_invalidate_item, 45 | .sni_destroy = (void (*)(sni_item_t *, void *))tray_destroy_item, 46 | }; 47 | 48 | static void tray_init ( Tray *self ) 49 | { 50 | TrayPrivate *priv; 51 | 52 | sni_listener_register(&tray_sni_listener, self); 53 | priv = tray_get_instance_private(TRAY(self)); 54 | priv->timer_h = g_timeout_add(100, (GSourceFunc)flow_grid_update, self); 55 | gtk_grid_set_column_homogeneous( 56 | GTK_GRID(base_widget_get_child(GTK_WIDGET(self))), FALSE); 57 | 58 | g_list_foreach(sni_item_get_list(), (GFunc)tray_item_new, self); 59 | } 60 | 61 | GtkWidget *tray_new ( void ) 62 | { 63 | return GTK_WIDGET(g_object_new(tray_get_type(), NULL)); 64 | } 65 | 66 | /*void tray_invalidate_all ( sni_item_t *sni ) 67 | { 68 | GList *iter; 69 | 70 | for(iter=trays; iter; iter=g_list_next(iter)) 71 | flow_item_invalidate(flow_grid_find_child(iter->data,sni)); 72 | } 73 | 74 | void tray_item_init_for_all ( sni_item_t *sni ) 75 | { 76 | GList *iter; 77 | 78 | for(iter=trays; iter; iter=g_list_next(iter)) 79 | tray_item_new(sni, iter->data); 80 | } 81 | 82 | void tray_item_destroy ( sni_item_t *sni ) 83 | { 84 | g_list_foreach(trays, (GFunc)flow_grid_delete_child, sni); 85 | } 86 | 87 | void tray_update ( void ) 88 | { 89 | GList *iter; 90 | 91 | for(iter=trays; iter; iter=g_list_next(iter)) 92 | flow_grid_update(iter->data); 93 | }*/ 94 | -------------------------------------------------------------------------------- /src/gui/tray.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRAY_H__ 2 | #define __TRAY_H__ 3 | 4 | #include "flowgrid.h" 5 | #include "sni.h" 6 | 7 | #define TRAY_TYPE (tray_get_type()) 8 | #define TRAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TRAY_TYPE, Tray)) 9 | #define TRAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TRAY_TYPE, TrayClass)) 10 | #define IS_TRAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TRAY_TYPE)) 11 | #define IS_TRAYCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TRAY_TYPE)) 12 | 13 | typedef struct _Tray Tray; 14 | typedef struct _TrayClass TrayClass; 15 | 16 | struct _Tray 17 | { 18 | FlowGrid item; 19 | }; 20 | 21 | struct _TrayClass 22 | { 23 | FlowGridClass parent_class; 24 | }; 25 | 26 | typedef struct _TrayPrivate TrayPrivate; 27 | 28 | struct _TrayPrivate 29 | { 30 | guint timer_h; 31 | }; 32 | 33 | GType tray_get_type ( void ); 34 | 35 | GtkWidget *tray_new(); 36 | void tray_item_init_for_all ( sni_item_t *sni ); 37 | void tray_item_destroy ( sni_item_t *sni ); 38 | void tray_update ( void ); 39 | void tray_invalidate_all ( sni_item_t *sni ); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/gui/trayitem.h: -------------------------------------------------------------------------------- 1 | #ifndef __SNIITEM_H__ 2 | #define __SNIITEM_H__ 3 | 4 | #include "flowitem.h" 5 | #include "sni.h" 6 | 7 | #define TRAY_ITEM_TYPE (tray_item_get_type()) 8 | #define TRAY_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TRAY_ITEM_TYPE, TrayItem)) 9 | #define TRAY_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TRAY_ITEM_TYPE, TrayItemClass)) 10 | #define IS_TRAY_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TRAY_ITEM_TYPE)) 11 | #define IS_TRAY_ITEMCLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TRAY_ITEM_TYPE)) 12 | 13 | typedef struct _TrayItem TrayItem; 14 | typedef struct _TrayItemClass TrayItemClass; 15 | 16 | struct _TrayItem 17 | { 18 | FlowItem item; 19 | }; 20 | 21 | struct _TrayItemClass 22 | { 23 | FlowItemClass parent_class; 24 | }; 25 | 26 | typedef struct _TrayItemPrivate TrayItemPrivate; 27 | 28 | struct _TrayItemPrivate 29 | { 30 | sni_item_t *sni; 31 | GtkWidget *button; 32 | GtkWidget *icon; 33 | GtkWidget *label; 34 | GtkWidget *tray; 35 | gboolean invalid; 36 | }; 37 | 38 | GType tray_item_get_type ( void ); 39 | 40 | GtkWidget *tray_item_new( sni_item_t *win, GtkWidget *tray ); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/ipc/sway.h: -------------------------------------------------------------------------------- 1 | #ifndef __SWAY_IPC_H__ 2 | #define __SWAY_IPC_H__ 3 | 4 | #include "scanner.h" 5 | 6 | void sway_ipc_init ( void ); 7 | void sway_ipc_client_init ( ScanFile *file ); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/locale1.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOCALE1_H__ 2 | #define __LOCALE1_H__ 3 | 4 | #include 5 | 6 | void locale1_init ( void ); 7 | const gchar *locale1_get_locale ( void ); 8 | 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /src/module.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __MODULE_H__ 3 | #define __MODULE_H__ 4 | 5 | #include 6 | 7 | #define MODULE_API_VERSION 3 8 | 9 | typedef struct _module_queue { 10 | GList *list; 11 | GMutex mutex; 12 | void *(*duplicate) (void *); 13 | void (*free) (void *); 14 | void *(*get_str) (void *, gchar *); 15 | void *(*get_num) (void *, gchar *); 16 | gboolean (*compare) (const void *, const void *); 17 | const gchar *trigger; 18 | gint limit; 19 | } module_queue_t; 20 | 21 | typedef void (*ModuleInvalidator)( void ); 22 | typedef gboolean (*ModuleInitializer)( void ); 23 | 24 | typedef struct { 25 | gboolean ready; 26 | gboolean active; 27 | gchar *interface; 28 | gchar *provider; 29 | void (*activate) (void); 30 | void (*deactivate) (void); 31 | void (*finalize) (void); 32 | } ModuleInterfaceV1; 33 | 34 | typedef struct { 35 | GList *list; 36 | ModuleInterfaceV1 *active; 37 | } ModuleInterfaceList; 38 | 39 | void module_queue_append ( module_queue_t *queue, void *item ); 40 | void module_queue_remove ( module_queue_t *queue ); 41 | void *module_queue_get_string ( module_queue_t *queue, gchar *param ); 42 | void *module_queue_get_numeric ( module_queue_t *queue, gchar *param ); 43 | 44 | gboolean module_load ( gchar *name ); 45 | void module_invalidate_all ( void ); 46 | void module_interface_select ( gchar *interface ); 47 | void module_interface_activate ( ModuleInterfaceV1 *iface ); 48 | void module_interface_deactivate ( ModuleInterfaceV1 *iface ); 49 | gchar *module_interface_provider_get ( gchar *interface ); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/scanner.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCANNER_H__ 2 | #define __SCANNER_H__ 3 | 4 | #include 5 | #include "vm/expr.h" 6 | #include "vm/vm.h" 7 | 8 | enum { 9 | SO_FILE = 0, 10 | SO_EXEC = 1, 11 | SO_CLIENT = 2 12 | }; 13 | 14 | enum { 15 | VF_CHTIME = 1, 16 | VF_NOGLOB = 2 17 | }; 18 | 19 | enum { 20 | VT_SUM = 1, 21 | VT_PROD, 22 | VT_LAST, 23 | VT_FIRST 24 | }; 25 | 26 | enum { 27 | SCANNER_TYPE_NONE = 0, 28 | SCANNER_TYPE_STR, 29 | SCANNER_TYPE_VAL, 30 | SCANNER_TYPE_PVAL, 31 | SCANNER_TYPE_COUNT, 32 | SCANNER_TYPE_TIME, 33 | SCANNER_TYPE_AGE 34 | }; 35 | 36 | typedef struct scan_file { 37 | gchar *fname; 38 | const gchar *trigger; 39 | gint flags; 40 | guchar source; 41 | time_t mtime; 42 | GList *vars; 43 | void *client; 44 | } ScanFile; 45 | 46 | typedef struct scan_var { 47 | expr_cache_t *expr; 48 | void *definition; 49 | gchar *str; 50 | guint vstate; 51 | double val; 52 | double pval; 53 | gint64 time; 54 | gint64 ptime; 55 | gint count; 56 | gint multi; 57 | guint type; 58 | gboolean invalid; 59 | gboolean inuse; 60 | ScanFile *file; 61 | } ScanVar; 62 | 63 | void scanner_invalidate ( void ); 64 | void scanner_var_reset ( ScanVar *var, gpointer dummy ); 65 | void scanner_update_json ( struct json_object *, ScanFile * ); 66 | GIOStatus scanner_file_update ( GIOChannel *, ScanFile *, gsize * ); 67 | int scanner_glob_file ( ScanFile * ); 68 | value_t scanner_get_value ( GQuark id, gchar ftype, gboolean update, 69 | expr_cache_t *expr ); 70 | void scanner_var_new ( gchar *, ScanFile *, gchar *, guint, gint ); 71 | void scanner_file_merge ( ScanFile *keep, ScanFile *temp ); 72 | GQuark scanner_parse_identifier ( const gchar *id, guint8 *dtype ); 73 | ScanFile *scanner_file_get ( gchar *trigger ); 74 | ScanFile *scanner_file_new ( gint , gchar *, gchar *, gint ); 75 | gboolean scanner_is_variable ( gchar *identifier ); 76 | void scanner_file_attach ( const gchar *trigger, ScanFile *file ); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/sfwbar.h: -------------------------------------------------------------------------------- 1 | #ifndef __SFWBAR_H__ 2 | #define __SFWBAR_H__ 3 | 4 | #include 5 | #include 6 | 7 | #if GLIB_MINOR_VERSION < 68 8 | #define g_memdup2(x,y) g_memdup(x,y) 9 | #endif 10 | 11 | void signal_subscribe ( void ); 12 | void action_lib_init ( void ); 13 | void hypr_ipc_init ( void ); 14 | void wayfire_ipc_init ( void ); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/signal.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2023- sfwbar maintainers 4 | */ 5 | 6 | #include 7 | #include "trigger.h" 8 | 9 | static gint signal_counter[255]; 10 | static gint signal_flag; 11 | 12 | static void signal_handler ( gint sig ) 13 | { 14 | if(sigSIGRTMAX) 15 | return; 16 | 17 | g_atomic_int_inc(&signal_counter[sig-SIGRTMIN]); 18 | g_atomic_int_set(&signal_flag, 1); 19 | } 20 | 21 | static gboolean signal_source_prepare( GSource *source, gint *timeout) 22 | { 23 | *timeout = -1; 24 | return signal_flag; 25 | } 26 | 27 | static gboolean signal_source_check( GSource *source ) 28 | { 29 | return signal_flag; 30 | } 31 | 32 | static gboolean signal_source_dispatch( GSource *source, GSourceFunc cb, 33 | gpointer data) 34 | { 35 | gchar *trigger; 36 | gint sig; 37 | 38 | g_atomic_int_set(&signal_flag, 0); 39 | for(sig=SIGRTMIN; sig 5 | #include "vm/vm.h" 6 | 7 | typedef void(*trigger_func_t)(void *, vm_store_t *); 8 | 9 | const gchar *trigger_add ( gchar *name, trigger_func_t func, void *data ); 10 | void trigger_remove ( gchar *name, trigger_func_t func, void *data ); 11 | void trigger_action_cb ( vm_closure_t *closure, vm_store_t *store ); 12 | const gchar *trigger_name_intern ( gchar *name ); 13 | void trigger_emit_with_data ( gchar *name, vm_store_t *store ); 14 | gboolean trigger_emit ( gchar *name ); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/util/datalist.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2025- sfwbar maintainers 4 | */ 5 | 6 | #include "util/datalist.h" 7 | 8 | datalist_t *datalist_new ( void ) 9 | { 10 | datalist_t *dlist; 11 | 12 | dlist = g_malloc0(sizeof(datalist_t)); 13 | g_datalist_init(&dlist->data); 14 | dlist->refcount = 1; 15 | 16 | return dlist; 17 | } 18 | 19 | datalist_t *datalist_ref ( datalist_t *dlist ) 20 | { 21 | dlist->refcount++; 22 | return dlist; 23 | } 24 | 25 | void datalist_unref ( datalist_t *dlist ) 26 | { 27 | dlist->refcount--; 28 | if(!(dlist->refcount)) 29 | { 30 | g_datalist_clear(&dlist->data); 31 | g_free(dlist); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/util/datalist.h: -------------------------------------------------------------------------------- 1 | #ifndef __DATALIST_H__ 2 | #define __DATALIST_H__ 3 | 4 | #include 5 | 6 | typedef struct _datalist_t { 7 | GData *data; 8 | gint refcount; 9 | } datalist_t; 10 | 11 | datalist_t *datalist_new ( void ); 12 | datalist_t *datalist_ref ( datalist_t *dlist ); 13 | void datalist_unref ( datalist_t *dlist ); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/util/file.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2020- sfwbar maintainers 4 | */ 5 | 6 | #include 7 | #include 8 | #include "meson.h" 9 | 10 | gchar *confname; 11 | gchar *sockname; 12 | 13 | gboolean file_test_read ( gchar *filename ) 14 | { 15 | if( !g_file_test(filename, G_FILE_TEST_EXISTS) ) 16 | return FALSE; 17 | if( access(filename, R_OK) == -1 ) 18 | return FALSE; 19 | return TRUE; 20 | } 21 | 22 | /* get xdg config file name, first try user xdg config directory, 23 | * if file doesn't exist, try system xdg data dirs */ 24 | gchar *get_xdg_config_file ( gchar *fname, gchar *extra ) 25 | { 26 | gchar *full, *dir; 27 | const gchar * const *xdg_data; 28 | gint i; 29 | 30 | if(fname && *fname == '/') 31 | { 32 | if(file_test_read(fname)) 33 | return g_strdup(fname); 34 | else 35 | return NULL; 36 | } 37 | 38 | if(confname) 39 | { 40 | dir = g_path_get_dirname(confname); 41 | full = g_build_filename ( dir, fname, NULL ); 42 | g_free(dir); 43 | if( file_test_read(full) ) 44 | return full; 45 | g_free(full); 46 | } 47 | 48 | full = g_build_filename ( g_get_user_config_dir(), "sfwbar", fname, NULL ); 49 | if( file_test_read(full) ) 50 | return full; 51 | g_free(full); 52 | 53 | xdg_data = g_get_system_data_dirs(); 54 | for(i=0;xdg_data[i];i++) 55 | { 56 | full = g_build_filename ( xdg_data[i], "sfwbar", fname, NULL ); 57 | if( file_test_read(full) ) 58 | return full; 59 | g_free(full); 60 | } 61 | 62 | full = g_build_filename( SYSTEM_CONF_DIR, fname, NULL); 63 | if( file_test_read(full) ) 64 | return full; 65 | g_free(full); 66 | 67 | if(!extra) 68 | return NULL; 69 | full = g_build_filename ( extra, fname, NULL ); 70 | if( file_test_read(full) ) 71 | return full; 72 | g_free(full); 73 | 74 | return NULL; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/util/file.h: -------------------------------------------------------------------------------- 1 | #ifndef __SFWBAR_FILE__ 2 | #define __SFWBAR_FILE__ 3 | 4 | #include 5 | 6 | gboolean file_test_read ( gchar *filename ); 7 | gchar *get_xdg_config_file ( gchar *fname, gchar *extra ); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/util/json.h: -------------------------------------------------------------------------------- 1 | #ifndef __JSON_H__ 2 | #define __JSON_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | gint socket_connect ( const gchar *sockaddr, gint to ); 9 | gssize recv_retry ( gint sock, gpointer buff, gssize len ); 10 | json_object *recv_json ( gint sock, gssize len ); 11 | 12 | const gchar *json_string_by_name ( struct json_object *obj, gchar *name ); 13 | gint64 json_int_by_name ( struct json_object *obj, gchar *name, gint64 defval); 14 | gboolean json_bool_by_name ( struct json_object *obj, gchar *name, gboolean defval); 15 | gdouble json_double_by_name ( struct json_object *obj, gchar *name, gdouble defval); 16 | struct json_object *json_array_by_name ( struct json_object *obj, gchar *key ); 17 | struct json_object *json_node_by_name ( struct json_object *json, gchar *key ); 18 | GdkRectangle json_rect_get ( struct json_object *json ); 19 | 20 | struct json_object *jpath_parse ( gchar *path, struct json_object *obj ); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/util/string.h: -------------------------------------------------------------------------------- 1 | #ifndef __SFWBAR_STRING_H__ 2 | #define __SFWBAR_STRING_H__ 3 | 4 | #include 5 | 6 | guint str_nhash ( gchar *str ); 7 | gboolean str_nequal ( gchar *str1, gchar *str2 ); 8 | gchar *str_replace ( gchar *str, gchar *old, gchar *new ); 9 | gchar *str_escape ( gchar *string ); 10 | void *ptr_pass ( void *ptr ); 11 | int md5_file( gchar *path, guchar output[16] ); 12 | gchar *numeric_to_string ( double num, gint dec ); 13 | gboolean pattern_match ( gchar **dict, gchar *string ); 14 | gboolean regex_match_list ( GList *dict, gchar *string ); 15 | void regex_list_add ( GList **list, gchar *pattern ); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/vm/expr.h: -------------------------------------------------------------------------------- 1 | #ifndef __EXPR_H__ 2 | #define __EXPR_H__ 3 | 4 | #include 5 | 6 | typedef struct expr_cache { 7 | gchar *definition; 8 | gchar *cache; 9 | GBytes *code; 10 | GtkWidget *widget; 11 | GdkEvent *event; 12 | gboolean eval; 13 | gint stack_depth; 14 | guint vstate; 15 | struct expr_cache *parent; 16 | } expr_cache_t; 17 | 18 | gboolean expr_cache_eval ( expr_cache_t *expr ); 19 | void expr_lib_init ( void ); 20 | expr_cache_t *expr_cache_new ( void ); 21 | expr_cache_t *expr_cache_new_with_code ( GBytes *code ); 22 | void expr_cache_set ( expr_cache_t *expr, gchar *def ); 23 | void expr_cache_free ( expr_cache_t *expr ); 24 | void expr_dep_add ( GQuark quark, expr_cache_t *expr ); 25 | void expr_dep_remove ( expr_cache_t *expr ); 26 | void expr_dep_trigger ( GQuark quark ); 27 | void expr_dep_dump ( void ); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/vm/func.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2025- sfwbar maintainers 4 | */ 5 | 6 | #include "vm/vm.h" 7 | #include "util/string.h" 8 | 9 | GHashTable *vm_func_table; 10 | 11 | void vm_func_init ( void ) 12 | { 13 | if(vm_func_table) 14 | return; 15 | vm_func_table = g_hash_table_new((GHashFunc)str_nhash, 16 | (GEqualFunc)str_nequal); 17 | } 18 | 19 | vm_function_t *vm_func_lookup ( gchar *name ) 20 | { 21 | vm_function_t *func; 22 | 23 | if( (func = (vm_function_t *)g_hash_table_lookup(vm_func_table, name)) ) 24 | return func; 25 | 26 | func = g_malloc0(sizeof(vm_function_t)); 27 | func->name = g_strdup(name); 28 | g_hash_table_insert(vm_func_table, func->name, func); 29 | 30 | return func; 31 | } 32 | 33 | void vm_func_add ( gchar *name, vm_func_t function, gboolean deterministic ) 34 | { 35 | vm_function_t *func; 36 | 37 | func = vm_func_lookup(name); 38 | 39 | func->ptr.function = function; 40 | func->flags |= (deterministic? VM_FUNC_DETERMINISTIC : 0); 41 | expr_dep_trigger(g_quark_from_string(name)); 42 | g_debug("function: registered '%s'", name); 43 | } 44 | 45 | void vm_func_add_user ( gchar *name, GBytes *code ) 46 | { 47 | vm_function_t *func; 48 | 49 | func = vm_func_lookup(name); 50 | func->ptr.code = code; 51 | func->flags = VM_FUNC_USERDEFINED; 52 | expr_dep_trigger(g_quark_from_string(name)); 53 | g_debug("function: registered '%s'", name); 54 | } 55 | 56 | void vm_func_remove ( gchar *name ) 57 | { 58 | vm_function_t *func; 59 | 60 | if( !(func = g_hash_table_lookup(vm_func_table, name)) ) 61 | return; 62 | 63 | func->ptr.function = NULL; 64 | } 65 | -------------------------------------------------------------------------------- /src/vm/value.c: -------------------------------------------------------------------------------- 1 | 2 | #include "vm/value.h" 3 | 4 | void value_free ( value_t v1 ) 5 | { 6 | if(value_is_string(v1)) 7 | g_free(v1.value.string); 8 | else if(value_is_array(v1)) 9 | g_array_unref(v1.value.array); 10 | } 11 | 12 | value_t value_array_concat ( value_t v1, value_t v2 ) 13 | { 14 | GArray *result; 15 | value_t new; 16 | gpointer data; 17 | gsize len; 18 | 19 | if(!value_is_array(v1) && !value_is_array(v1)) 20 | return value_na; 21 | 22 | if(!value_is_array(v1)) 23 | { 24 | new = value_dup(v1); 25 | result = g_array_prepend_vals(g_array_ref(v2.value.array), &new, 1); 26 | } 27 | else if(!value_is_array(v2)) 28 | { 29 | new = value_dup(v2); 30 | result = g_array_append_vals(g_array_ref(v1.value.array), &new, 1); 31 | } 32 | else 33 | { 34 | data = g_array_steal(v2.value.array, &len); 35 | result = g_array_append_vals(g_array_ref(v1.value.array), data, len); 36 | } 37 | 38 | return value_new_array(result); 39 | } 40 | 41 | value_t value_dup_array ( value_t v1 ) 42 | { 43 | GArray *array; 44 | value_t v2; 45 | gsize i; 46 | 47 | array = g_array_sized_new(FALSE, FALSE, sizeof(value_t), v1.value.array->len); 48 | g_array_set_clear_func(array, (GDestroyNotify)value_free); 49 | 50 | for(i=0; ilen;i++) 51 | { 52 | v2 = value_dup(g_array_index(v1.value.array, value_t, i)); 53 | g_array_append_val(array, v2); 54 | } 55 | return value_new_array(array); 56 | } 57 | 58 | value_t value_dup ( value_t v1 ) 59 | { 60 | if(value_is_string(v1)) 61 | return value_new_string(g_strdup(v1.value.string)); 62 | if(value_is_array(v1)) 63 | return value_dup_array(v1); 64 | return v1; 65 | } 66 | -------------------------------------------------------------------------------- /src/vm/value.h: -------------------------------------------------------------------------------- 1 | #ifndef __VALUE_H__ 2 | #define __VALUE_H__ 3 | 4 | #include 5 | 6 | enum expr_type_t { 7 | EXPR_TYPE_NUMERIC, 8 | EXPR_TYPE_STRING, 9 | EXPR_TYPE_ARRAY, 10 | EXPR_TYPE_BOOLEAN, // Not in use 11 | EXPR_TYPE_NA 12 | }; 13 | 14 | typedef struct { 15 | guint8 type; 16 | union { 17 | gboolean boolean; 18 | gdouble numeric; 19 | gchar *string; 20 | GArray *array; 21 | } value; 22 | } value_t; 23 | 24 | extern const value_t value_na; 25 | 26 | #define value_new_string(v) \ 27 | ((value_t){.type=EXPR_TYPE_STRING, .value.string=(v)}) 28 | #define value_new_numeric(v) \ 29 | ((value_t){.type=EXPR_TYPE_NUMERIC, .value.numeric=(v)}) 30 | #define value_new_array(v) \ 31 | ((value_t){.type=EXPR_TYPE_ARRAY, .value.array=(v)}) 32 | #define value_new_na() (value_na) 33 | 34 | #define value_is_string(v) ((v).type == EXPR_TYPE_STRING) 35 | #define value_is_numeric(v) ((v).type == EXPR_TYPE_NUMERIC) 36 | #define value_is_na(v) ((v).type == EXPR_TYPE_NA) 37 | #define value_is_array(v) ((v).type == EXPR_TYPE_ARRAY) 38 | 39 | #define value_like_string(v) (value_is_string(v) || value_is_na(v)) 40 | #define value_like_numeric(v) (value_is_numeric(v) || value_is_na(v)) 41 | #define value_like_array(v) (value_is_array(v) || value_is_na(v)) 42 | 43 | #define value_get_string(v) \ 44 | ((value_is_string(v)&&v.value.string)?v.value.string:"") 45 | #define value_get_numeric(v) (value_is_numeric(v)?v.value.numeric:0) 46 | #define value_get_array(v) (value_is_array(v)?v.value.array:NULL) 47 | 48 | #define value_as_numeric(v) (value_like_numeric(v)? value_get_numeric(v) : \ 49 | (value_is_string(v)? g_ascii_strtod(v.value.string, NULL) : 0)) 50 | 51 | void value_free ( value_t ); 52 | value_t value_dup ( value_t ); 53 | value_t value_array_concat ( value_t v1, value_t v2 ); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/vm/var.h: -------------------------------------------------------------------------------- 1 | #ifndef __VAR_H__ 2 | #define __VAR_H__ 3 | 4 | #include 5 | 6 | G_BEGIN_DECLS 7 | 8 | #define VAR_TYPE ivm_var_get_type() 9 | G_DECLARE_DERIVABLE_TYPE (VmVar, vm_var, VM, VAR, GObject) 10 | 11 | struct _VmVarClass { 12 | GObjectClass parent_class; 13 | }; 14 | 15 | struct _VmVarPrivate { 16 | value_t val; 17 | }; 18 | 19 | G_END_DECLS 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/wayland.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2023- sfwbar maintainers 4 | */ 5 | 6 | #include 7 | #include "wayland.h" 8 | #include "gui/monitor.h" 9 | #include "xdg-output-unstable-v1.h" 10 | #include "wlr-foreign-toplevel-management-unstable-v1.h" 11 | #include "wlr-layer-shell-unstable-v1.h" 12 | 13 | static GList *wayland_ifaces; 14 | static struct wl_registry *wayland_registry; 15 | static gboolean wayland_init_complete; 16 | 17 | static void handle_global(void *data, struct wl_registry *registry, 18 | uint32_t name, const gchar *interface, uint32_t version) 19 | { 20 | wayland_iface_t *iface; 21 | 22 | if(wayland_init_complete) 23 | return; 24 | 25 | iface = g_malloc0(sizeof(wayland_iface_t)); 26 | iface->iface = g_strdup(interface); 27 | iface->global = name; 28 | iface->version = version; 29 | wayland_ifaces = g_list_append(wayland_ifaces, iface); 30 | } 31 | 32 | gpointer wayland_iface_register ( const gchar *interface, 33 | guint32 min_ver, guint32 max_ver, const void *impl ) 34 | { 35 | GList *iter; 36 | wayland_iface_t *iface; 37 | 38 | for(iter=wayland_ifaces; iter; iter=g_list_next(iter)) 39 | { 40 | iface = iter->data; 41 | if(iface->version >= min_ver && !g_strcmp0(iface->iface, interface)) 42 | return wl_registry_bind(wayland_registry, iface->global, impl, 43 | MIN(iface->version, max_ver)); 44 | } 45 | return NULL; 46 | } 47 | 48 | static void handle_global_remove(void *data, struct wl_registry *registry, 49 | uint32_t name) 50 | { 51 | } 52 | 53 | static const struct wl_registry_listener registry_listener = { 54 | .global = handle_global, 55 | .global_remove = handle_global_remove 56 | }; 57 | 58 | void wayland_init ( void ) 59 | { 60 | struct wl_display *wdisp; 61 | 62 | if(!(wdisp = gdk_wayland_display_get_wl_display(gdk_display_get_default())) ) 63 | g_error("Can't get wayland display\n"); 64 | 65 | wayland_registry = wl_display_get_registry(wdisp); 66 | wl_registry_add_listener(wayland_registry, ®istry_listener, NULL); 67 | wl_display_roundtrip(wdisp); 68 | wayland_init_complete = TRUE; 69 | 70 | wl_display_roundtrip(wdisp); 71 | wl_display_roundtrip(wdisp); 72 | } 73 | -------------------------------------------------------------------------------- /src/wayland.h: -------------------------------------------------------------------------------- 1 | #ifndef __WAYLAND_H__ 2 | #define __WAYLAND_H__ 3 | 4 | #include 5 | 6 | typedef struct _wayland_iface { 7 | gchar *iface; 8 | guint32 global; 9 | guint32 version; 10 | } wayland_iface_t; 11 | 12 | void wayland_init ( void ); 13 | gpointer wayland_iface_register ( const gchar *interface, 14 | guint32 min_ver, guint32 max_ver, const void *impl ); 15 | void foreign_toplevel_init ( void ); 16 | void cw_init ( void ); 17 | void ew_init ( void ); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/window.c: -------------------------------------------------------------------------------- 1 | /* This entire file is licensed under GNU General Public License v3.0 2 | * 3 | * Copyright 2023- sfwbar maintainers 4 | */ 5 | 6 | #include "window.h" 7 | 8 | void window_ref_free ( GtkWidget *self ) 9 | { 10 | GList **refs; 11 | 12 | refs = g_object_get_data(G_OBJECT(self),"window_refs"); 13 | 14 | if(!refs) 15 | return; 16 | 17 | g_list_free(*refs); 18 | g_free(refs); 19 | g_object_set_data(G_OBJECT(self),"window_refs", NULL); 20 | } 21 | 22 | void window_ref ( GtkWidget *self, GtkWidget *ref ) 23 | { 24 | GList **refs; 25 | 26 | refs = g_object_get_data(G_OBJECT(self),"window_refs"); 27 | if(!refs) 28 | { 29 | g_object_set_data_full(G_OBJECT(self),"window_refs", 30 | g_malloc0(sizeof(GList *)),(GDestroyNotify)window_ref_free); 31 | refs = g_object_get_data(G_OBJECT(self),"window_refs"); 32 | } 33 | 34 | if(refs && !g_list_find(*refs, ref)) 35 | *refs = g_list_prepend(*refs ,ref); 36 | g_signal_connect(G_OBJECT(ref),"unmap",G_CALLBACK(window_unref),self); 37 | } 38 | 39 | void window_unref ( GtkWidget *ref, GtkWidget *self ) 40 | { 41 | GList **refs; 42 | void (*unref_func)( gpointer); 43 | 44 | refs = g_object_get_data(G_OBJECT(self),"window_refs"); 45 | if(!refs) 46 | return; 47 | 48 | *refs = g_list_remove(*refs, ref); 49 | if(!*refs && (unref_func = g_object_get_data(G_OBJECT(self), "unref_func"))) 50 | unref_func(self); 51 | } 52 | 53 | gboolean window_ref_check ( GtkWidget *self ) 54 | { 55 | GList **refs; 56 | 57 | refs = g_object_get_data(G_OBJECT(self),"window_refs"); 58 | 59 | return !!(refs && *refs); 60 | } 61 | 62 | void window_set_unref_func ( GtkWidget *self, void (*func)(gpointer) ) 63 | { 64 | g_object_set_data(G_OBJECT(self), "unref_func", func); 65 | } 66 | 67 | void window_collapse_popups ( GtkWidget *self ) 68 | { 69 | GList *iter, **refs; 70 | 71 | refs = g_object_get_data(G_OBJECT(self),"window_refs"); 72 | if(!refs) 73 | return; 74 | 75 | for(iter=*refs; iter; iter=g_list_next(iter)) 76 | { 77 | if(iter->data == self) 78 | continue; 79 | if(GTK_IS_WINDOW(iter->data) && 80 | gtk_window_get_window_type(GTK_WINDOW(iter->data)) == GTK_WINDOW_POPUP) 81 | window_collapse_popups(iter->data); 82 | 83 | if(GTK_IS_WINDOW(iter->data)) 84 | gtk_widget_hide(iter->data); 85 | if(GTK_IS_MENU(iter->data)) 86 | { 87 | gtk_menu_popdown(iter->data); 88 | iter = *refs; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef __WINDOW_H__ 2 | #define __WINDOW_H__ 3 | 4 | #include 5 | 6 | void window_ref ( GtkWidget *self, GtkWidget *ref ); 7 | void window_unref ( GtkWidget *ref, GtkWidget *self ); 8 | gboolean window_ref_check ( GtkWidget *self ); 9 | void window_set_unref_func ( GtkWidget *self, void (*func)(gpointer) ); 10 | void window_collapse_popups ( GtkWidget *self ); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/workspace.h: -------------------------------------------------------------------------------- 1 | #ifndef __WORKSPACE_H__ 2 | #define __WORKSPACE_H__ 3 | 4 | #include 5 | 6 | enum { 7 | WS_STATE_FOCUSED = 0x0001, 8 | WS_STATE_VISIBLE = 0x0002, 9 | WS_STATE_URGENT = 0x0004, 10 | WS_STATE_INVALID = 0x0080, 11 | WS_STATE_ALL = 0x00ff, 12 | 13 | WS_CAP_ACTIVATE = 0x0100, 14 | WS_CAP_ALL = 0xff00, 15 | }; 16 | 17 | typedef struct workspace_s { 18 | gpointer id; 19 | gchar *name; 20 | guint32 state; 21 | gint refcount; 22 | } workspace_t; 23 | 24 | struct workspace_api { 25 | void (*set_workspace) ( workspace_t * ); 26 | guint (*get_geom) ( gpointer, GdkRectangle *, gpointer, GdkRectangle **, 27 | GdkRectangle *, gint * ); 28 | gboolean (*get_can_create) ( void ); 29 | gchar *(*get_monitor) ( gpointer ); 30 | }; 31 | 32 | typedef struct _workspace_listener { 33 | void (*workspace_new) ( workspace_t *, void *); 34 | void (*workspace_invalidate) ( workspace_t *, void *); 35 | void (*workspace_destroy) ( workspace_t *, void *); 36 | void *data; 37 | } workspace_listener_t; 38 | 39 | #define WORKSPACE_LISTENER(x) ((workspace_listener_t *)(x)) 40 | #define PAGER_PIN_ID (GINT_TO_POINTER(-1)) 41 | #define WORKSPACE(x) ((workspace_t *)(x)) 42 | 43 | void workspace_api_register ( struct workspace_api *new ); 44 | gboolean workspace_api_check ( void ); 45 | void workspace_listener_register ( workspace_listener_t *, gpointer ); 46 | void workspace_listener_remove ( void *data ); 47 | workspace_t *workspace_new ( gpointer id ); 48 | void workspace_commit ( workspace_t *ws ); 49 | void workspace_set_focus ( gpointer id ); 50 | void workspace_set_state ( workspace_t *ws, guint32 state ); 51 | void workspace_set_caps ( workspace_t *ws, guint32 caps ); 52 | void workspace_set_name ( workspace_t *ws, const gchar *name ); 53 | void workspace_set_active ( workspace_t *ws, const gchar *output ); 54 | gpointer workspace_get_active ( GtkWidget *widget ); 55 | gboolean workspace_is_focused ( workspace_t *ws ); 56 | gpointer workspace_id_from_name ( const gchar *name ); 57 | workspace_t *workspace_from_id ( gpointer id ); 58 | gpointer workspace_get_focused ( void ); 59 | void workspace_activate ( workspace_t *ws ); 60 | guint workspace_get_geometry ( gpointer wid, GdkRectangle *wloc, gpointer wsid, 61 | GdkRectangle **wins, GdkRectangle *spc, gint *focus); 62 | gchar *workspace_get_monitor ( gpointer wsid ); 63 | gboolean workspace_get_can_create ( void ); 64 | void workspace_pin_add ( gchar *pin ); 65 | GList *workspace_get_list ( void ); 66 | workspace_t *workspace_from_name ( const gchar *name ); 67 | void workspace_ref ( gpointer id ); 68 | void workspace_unref ( gpointer id ); 69 | 70 | #endif 71 | --------------------------------------------------------------------------------