Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package pasystray for openSUSE:Factory 
checked in at 2022-05-04 15:11:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/pasystray (Old)
 and      /work/SRC/openSUSE:Factory/.pasystray.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "pasystray"

Wed May  4 15:11:00 2022 rev:10 rq:974795 version:0.8.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/pasystray/pasystray.changes      2021-03-05 
13:45:14.679620467 +0100
+++ /work/SRC/openSUSE:Factory/.pasystray.new.1538/pasystray.changes    
2022-05-04 15:11:23.084189298 +0200
@@ -1,0 +2,15 @@
+Tue May  3 18:17:39 UTC 2022 - Ferdinand Thiessen <r...@fthiessen.de>
+
+- Update to version 0.8.0
+  * volume: calculate notify value to always be between 0-100
+    fixes volume-max not working
+  * Fix null unref in pulseaudio_terminate
+  * Prefer symbolic icons, use microphone sensitivity icons.
+  * Import X11 volume control key grabber from pa-applet and
+    use for volume control
+  * Use volume max for icon instead of avg
+  * Listen to activate events of menu items
+    The new `activate` handlers substitute the current click
+    handlers for default left click events
+
+-------------------------------------------------------------------

Old:
----
  pasystray-0.7.1.tar.gz

New:
----
  pasystray-0.8.0.tar.gz

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

Other differences:
------------------
++++++ pasystray.spec ++++++
--- /var/tmp/diff_new_pack.jn4SmN/_old  2022-05-04 15:11:23.620189957 +0200
+++ /var/tmp/diff_new_pack.jn4SmN/_new  2022-05-04 15:11:23.624189961 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package pasystray
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,21 +16,14 @@
 #
 
 
-%if 0%{?suse_version} == 1315
-%define build_wayland_backend 0
-%define stdc99 1
-%else
-%define build_wayland_backend 1
-%define stdc99 0
-%endif
 Name:           pasystray
-Version:        0.7.1
+Version:        0.8.0
 Release:        0
 Summary:        PulseAudio system tray
 License:        LGPL-2.1-or-later
 Group:          System/GUI/Other
 URL:            https://github.com/christophgysin/pasystray
-Source:         
https://github.com/christophgysin/pasystray/archive/pasystray-%{version}.tar.gz
+Source:         
https://github.com/christophgysin/pasystray/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz
 BuildRequires:  automake
 BuildRequires:  pkgconfig
 BuildRequires:  update-desktop-files
@@ -40,10 +33,12 @@
 BuildRequires:  pkgconfig(gdk-3.0)
 BuildRequires:  pkgconfig(gdk-broadway-3.0)
 BuildRequires:  pkgconfig(gdk-x11-3.0)
+BuildRequires:  pkgconfig(gdk-wayland-3.0)
 BuildRequires:  pkgconfig(gtk+-3.0)
 BuildRequires:  pkgconfig(gtk+-broadway-3.0)
 BuildRequires:  pkgconfig(gtk+-unix-print-3.0)
 BuildRequires:  pkgconfig(gtk+-x11-3.0)
+BuildRequires:  pkgconfig(gtk+-wayland-3.0)
 BuildRequires:  pkgconfig(libnotify)
 BuildRequires:  pkgconfig(libpulse)
 BuildRequires:  pkgconfig(libpulse-mainloop-glib)
@@ -57,10 +52,6 @@
 Suggests:       paprefs
 Suggests:       pavucontrol
 Suggests:       pavumeter
-%if %{build_wayland_backend}
-BuildRequires:  pkgconfig(gdk-wayland-3.0)
-BuildRequires:  pkgconfig(gtk+-wayland-3.0)
-%endif
 
 %description
 A replacement for the deprecated padevchooser
@@ -68,15 +59,12 @@
 Pasystray allows setting the default PulseAudio source/sink and moving streams 
on the fly between sources/sinks without restarting the client applications.
 
 %prep
-%setup -q -n %{name}-%{name}-%{version}
+%setup -q
 
 %build
-%if %{stdc99}
-export CFLAGS="%{optflags} --std=c99"
-%endif
 autoreconf -fi
 %configure --sysconfdir=%{_sysconfdir}
-make %{?_smp_mflags}
+%make_build
 
 %install
 %make_install

++++++ pasystray-0.7.1.tar.gz -> pasystray-0.8.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pasystray-pasystray-0.7.1/.github/workflows/build.yml 
new/pasystray-0.8.0/.github/workflows/build.yml
--- old/pasystray-pasystray-0.7.1/.github/workflows/build.yml   1970-01-01 
01:00:00.000000000 +0100
+++ new/pasystray-0.8.0/.github/workflows/build.yml     2021-10-21 
20:54:40.000000000 +0200
@@ -0,0 +1,52 @@
+name: build
+
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        env:
+          - { CC: gcc, CFLAGS: --std=c99 }
+          - { CC: gcc, CFLAGS: --std=c99, EXTRA_CONF: --with-gtk=2 }
+          - { CC: gcc, CFLAGS: --std=c99, EXTRA_CONF: --disable-avahi }
+          - { CC: gcc, CFLAGS: --std=c99, EXTRA_CONF: --disable-notify }
+          - { CC: gcc, CFLAGS: --std=c99, EXTRA_CONF: --disable-x11 }
+          - { CC: gcc, CFLAGS: --std=c99, EXTRA_CONF: --disable-statusicon }
+          - { CC: gcc, CFLAGS: --std=c99, EXTRA_CONF: --disable-appindicator}
+          - { CC: gcc, CFLAGS: --std=c11 }
+          - { CC: clang, CFLAGS: --std=c99 }
+          - { CC: clang, CFLAGS: --std=c11 }
+    env: ${{ matrix.env }}
+    steps:
+    - name: apt-get update
+      run: sudo apt-get update
+    - name: apt-get install
+      run: >
+        sudo apt-get install --no-install-recommends
+        libgtk2.0-dev
+        libgtk-3-dev
+        libpulse-dev
+        libnotify-dev
+        libappindicator3-dev
+    - name: CC version
+      run: $CC --version
+    - name: git checkout
+      uses: actions/checkout@v2
+    - name: autotools
+      run: |
+        aclocal
+        autoconf
+        autoheader
+        automake --add-missing
+    - name: configure
+      run: ./configure ${EXTRA_CONF:-} || (cat config.log; exit 1)
+    - name: make
+      run: make
+    - name: make test
+      run: make test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/.travis.sh 
new/pasystray-0.8.0/.travis.sh
--- old/pasystray-pasystray-0.7.1/.travis.sh    2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/.travis.sh      1970-01-01 01:00:00.000000000 +0100
@@ -1,14 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-
-export CC=${USE_CC:-$CC}
-
-$CC --version
-
-aclocal
-autoconf
-autoheader
-automake --add-missing
-./configure ${EXTRA_CONF:-} || (cat config.log; exit 1)
-make
-make test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/.travis.yml 
new/pasystray-0.8.0/.travis.yml
--- old/pasystray-pasystray-0.7.1/.travis.yml   2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/.travis.yml     1970-01-01 01:00:00.000000000 +0100
@@ -1,27 +0,0 @@
-addons:
-  apt:
-    sources:
-      - ubuntu-toolchain-r-test
-      - llvm-toolchain-precise-3.7
-    packages:
-      - gcc-4.9
-      - clang-3.7
-      - libgtk-3-dev
-      - libpulse-dev
-      - libnotify-dev
-      - libappindicator3-dev
-language: c
-script: ./.travis.sh
-env:
-  - CFLAGS=--std=c99
-  - CFLAGS=--std=c99 EXTRA_CONF=--with-gtk=2
-  - CFLAGS=--std=c99 EXTRA_CONF=--disable-avahi
-  - CFLAGS=--std=c99 EXTRA_CONF=--disable-notify
-  - CFLAGS=--std=c99 EXTRA_CONF=--disable-x11
-  - CFLAGS=--std=c99 EXTRA_CONF=--disable-statusicon
-  - CFLAGS=--std=c99 EXTRA_CONF=--disable-appindicator
-  - USE_CC=gcc-4.9 CFLAGS=--std=c99
-  - USE_CC=gcc-4.9 CFLAGS=--std=c11
-  - USE_CC=clang-3.7 CFLAGS=--std=c99
-  - USE_CC=clang-3.7 CFLAGS=--std=c11
-sudo: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/README.md 
new/pasystray-0.8.0/README.md
--- old/pasystray-pasystray-0.7.1/README.md     2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/README.md       2021-10-21 20:54:40.000000000 +0200
@@ -1,6 +1,6 @@
 PulseAudio System Tray
 ======================
-[![Build 
Status](https://travis-ci.org/christophgysin/pasystray.png?branch=master)](https://travis-ci.org/christophgysin/pasystray)
+[![build](https://github.com/christophgysin/pasystray/actions/workflows/build.yml/badge.svg)](https://github.com/christophgysin/pasystray/actions/workflows/build.yml)
 
 A replacement for the deprecated padevchooser.
 
@@ -39,9 +39,9 @@
 
 over source/sink:
 * scroll up/down: adjust the volume of respective stream
-* left-click: set as default sink/source
+* left-click: set as default source/sink
 * middle-click / alt + left-click: toggle mute
-* right-click: open menu to rename source/sink
+* right-click: open menu to move all outputs/inputs to this source/sink or 
rename it
 
 over playback/record stream:
 * scroll up/down: adjust the volume of respective stream
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/configure.ac 
new/pasystray-0.8.0/configure.ac
--- old/pasystray-pasystray-0.7.1/configure.ac  2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/configure.ac    2021-10-21 20:54:40.000000000 +0200
@@ -1,6 +1,6 @@
 #  This file is part of PaSystray
 #
-#  Copyright (C) 2011-2019  Christoph Gysin
+#  Copyright (C) 2011-2021  Christoph Gysin
 #
 #  PaSystray is free software; you can redistribute it and/or modify
 #  it under the terms of the GNU Lesser General Public License as
@@ -19,7 +19,7 @@
 
 AC_PREREQ([2.68])
 
-AC_INIT([pasystray], [0.7.1], [christoph.gy...@gmail.com], [pasystray],
+AC_INIT([pasystray], [0.8.0], [christoph.gy...@gmail.com], [pasystray],
         [http://github.com/christophgysin/pasystray])
 AC_CONFIG_SRCDIR([src/pasystray.c])
 AC_CONFIG_HEADERS([src/config.h])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/man/pasystray.1 
new/pasystray-0.8.0/man/pasystray.1
--- old/pasystray-pasystray-0.7.1/man/pasystray.1       2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/man/pasystray.1 2021-10-21 20:54:40.000000000 +0200
@@ -53,11 +53,11 @@
 .IP \[bu]
 Scroll up/down: adjust volume
 .IP \[bu]
-Left-click: set as default sink/source
+Left-click: set as default source/sink
 .IP \[bu]
 Middle-click / Alt + Left-click: toggle mute
 .IP \[bu]
-Right-click: rename
+Right-click: open menu to move all outputs/inputs to this source/sink or 
rename it
 .LP
 Playback/record stream menu item:
 .IP \[bu]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/Makefile.am 
new/pasystray-0.8.0/src/Makefile.am
--- old/pasystray-pasystray-0.7.1/src/Makefile.am       2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/src/Makefile.am 2021-10-21 20:54:40.000000000 +0200
@@ -50,6 +50,12 @@
     x11-property.c \
     x11-property.h
 
+if HAVE_X11
+pasystray_SOURCES += \
+    x11-key-grabber.c \
+    x11-key-grabber.h
+endif
+
 pasystray_LDADD = \
     $(AM_LDADD) \
     $(GTK_LIBS) \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/menu_info.c 
new/pasystray-0.8.0/src/menu_info.c
--- old/pasystray-pasystray-0.7.1/src/menu_info.c       2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/src/menu_info.c 2021-10-21 20:54:40.000000000 +0200
@@ -369,6 +369,8 @@
             break;
     }
 
+    g_signal_connect(item->widget, "activate",
+            G_CALLBACK(menu_info_item_activated), item);
     g_signal_connect(item->widget, "button-press-event",
             G_CALLBACK(menu_info_item_clicked), item);
     gtk_widget_add_events(item->widget, GDK_SCROLL_MASK);
@@ -448,6 +450,9 @@
 
     g_signal_connect(subitem->widget, "button-press-event",
             G_CALLBACK(menu_info_subitem_clicked), subitem);
+
+    g_signal_connect(subitem->widget, "activate",
+            G_CALLBACK(menu_info_subitem_activated), subitem);
 }
 
 void menu_info_subitem_update(menu_info_t* mi, uint32_t index, const char* 
name,
@@ -500,6 +505,23 @@
     return g_hash_table_find(mi->items, desc_equal, (gpointer)desc);
 }
 
+void menu_info_item_activated(GtkWidget* item, menu_info_item_t* mii)
+{
+    if (GTK_IS_CHECK_MENU_ITEM(item)
+            && !gtk_check_menu_item_get_active(GTK_MENU_ITEM(item)))
+    {
+        /* Ignore activation of deselected item  */
+        return;
+    }
+
+    g_debug("[menu_info] subitem activated: %s %s",
+            menu_info_type_name(mii->menu_info->type),
+            mii->name);
+
+    /* on left-click, set device as default */
+    pulseaudio_set_default(mii);
+}
+
 void menu_info_item_clicked(GtkWidget* item, GdkEventButton* event,
         menu_info_item_t* mii)
 {
@@ -573,13 +595,18 @@
     }
 }
 
-void menu_info_subitem_clicked(GtkWidget* item, GdkEventButton* event,
-        menu_info_item_t* mii)
-{
-    g_debug("[menu_info] subitem clicked mod:%s%s button:%i",
-            (event->state & GDK_CONTROL_MASK) ? "[ctrl]" : "",
-            (event->state & GDK_MOD1_MASK) ? "[alt]" : "",
-            event->button);
+void menu_info_subitem_activated(GtkWidget* item, menu_info_item_t* mii) {
+
+    if (GTK_IS_CHECK_MENU_ITEM(item)
+            && !gtk_check_menu_item_get_active(GTK_MENU_ITEM(item)))
+    {
+        /* Ignore activation of deselected item  */
+        return;
+    }
+
+    g_debug("[menu_info] subitem activated: %s %s",
+            menu_info_type_name(mii->menu_info->type),
+            mii->name);
 
     switch(mii->menu_info->type)
     {
@@ -597,6 +624,15 @@
     }
 }
 
+void menu_info_subitem_clicked(GtkWidget* item, GdkEventButton* event,
+        menu_info_item_t* mii)
+{
+    g_debug("[menu_info] subitem clicked mod:%s%s button:%i",
+            (event->state & GDK_CONTROL_MASK) ? "[ctrl]" : "",
+            (event->state & GDK_MOD1_MASK) ? "[alt]" : "",
+            event->button);
+}
+
 void menu_info_item_move_all_cb(GtkWidget* item, GdkEventButton* event, void* 
userdata)
 {
     menu_info_item_t* mii = userdata;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/menu_info.h 
new/pasystray-0.8.0/src/menu_info.h
--- old/pasystray-pasystray-0.7.1/src/menu_info.h       2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/src/menu_info.h 2021-10-21 20:54:40.000000000 +0200
@@ -58,8 +58,11 @@
 struct settings_t_ {
     int volume_max;
     int volume_inc;
+    gboolean reverse_scroll;
     gboolean icon_tooltip;
     gboolean monitors;
+    // Grab volume control keys
+    gboolean key_grabbing;
     // Notification options below
     gboolean n_new;
     gboolean n_sink;
@@ -127,10 +130,12 @@
 menu_info_item_t* menu_info_item_get_by_name(menu_info_t* mi, const char* 
name);
 menu_info_item_t* menu_info_item_get_by_desc(menu_info_t* mi, const char* 
desc);
 
+void menu_info_item_activated(GtkWidget* item, menu_info_item_t* mii);
 void menu_info_item_clicked(GtkWidget* item, GdkEventButton* event,
         menu_info_item_t* mii);
 void menu_info_item_scrolled(GtkWidget* item, GdkEventScroll* event,
         menu_info_item_t* mii);
+void menu_info_subitem_activated(GtkWidget* item, menu_info_item_t* mii);
 void menu_info_subitem_clicked(GtkWidget* item, GdkEventButton* event,
         menu_info_item_t* mii);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/options.c 
new/pasystray-0.8.0/src/options.c
--- old/pasystray-pasystray-0.7.1/src/options.c 2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/src/options.c   2021-10-21 20:54:40.000000000 +0200
@@ -28,11 +28,13 @@
 static gboolean version = FALSE;
 static gboolean debug = FALSE;
 static int volume_max = 0;
-static int volume_inc = 1;
+static int volume_inc = 2;
+static gboolean reverse_scroll = FALSE;
 static gboolean icon_tooltip = TRUE;
 static gboolean no_notify = FALSE;
 static gboolean always_notify = FALSE;
 static gboolean monitors = FALSE;
+static gboolean key_grabbing = FALSE;
 static gchar **notify_mode;
 
 static GOptionEntry entries[] =
@@ -41,13 +43,16 @@
     { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Print debugging 
information", NULL },
     { "volume-max", 'm', 0, G_OPTION_ARG_INT, &volume_max, "Maximum volume (in 
percent)", "N" },
     { "volume-inc", 'i', 0, G_OPTION_ARG_INT, &volume_inc, "Volume increment", 
"N" },
-    { "no-icon-tooltip", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE,
+    { "reverse-scroll", 'r', 0, G_OPTION_ARG_NONE,
+       &reverse_scroll, "Reverse volume scroll direction", NULL },
+    { "no-icon-tooltip", 't', 0, G_OPTION_ARG_NONE,
         &icon_tooltip, "Disable the status icon tooltip for the connected 
state", NULL },
     { "no-notify", 'n', 0, G_OPTION_ARG_NONE, &no_notify,
         "Deprecated, use --notify=none instead", NULL },
     { "always-notify", 'a', 0, G_OPTION_ARG_NONE, &always_notify,
         "Deprecated, use --notify=all instead", NULL },
     { "include-monitors", 'n', 0, G_OPTION_ARG_NONE, &monitors, "Include 
monitor sources", NULL },
+    { "key-grabbing",  'g', 0, G_OPTION_ARG_NONE, &key_grabbing, "Grab volume 
control keys", NULL },
     { "notify", 'N', 0, G_OPTION_ARG_STRING_ARRAY, &notify_mode,
         "Set notification options, use --notify=help for a list of valid 
options", "OPTION" },
     { .long_name = NULL }
@@ -114,12 +119,13 @@
         settings->volume_max = volume_max;
     }
 
-    settings->volume_inc = 1;
+    settings->volume_inc = 2;
     if(volume_inc > 0)
     {
         settings->volume_inc = volume_inc;
     }
 
+    settings->reverse_scroll = reverse_scroll;
     settings->icon_tooltip = icon_tooltip;
 
     notify_default(settings);
@@ -212,4 +218,5 @@
     }
 
     settings->monitors = monitors;
+    settings->key_grabbing = key_grabbing;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/pasystray.c 
new/pasystray-0.8.0/src/pasystray.c
--- old/pasystray-pasystray-0.7.1/src/pasystray.c       2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/src/pasystray.c 2021-10-21 20:54:40.000000000 +0200
@@ -31,6 +31,7 @@
 #include "pulseaudio.h"
 #include "avahi.h"
 #include "x11-property.h"
+#include "x11-key-grabber.h"
 
 static GMainLoop* loop;
 static menu_infos_t* mis;
@@ -51,7 +52,7 @@
 
     init(&settings);
     g_main_loop_run(loop);
-    destroy();
+    destroy(&settings);
 
     return EXIT_SUCCESS;
 }
@@ -73,6 +74,11 @@
 
     pulseaudio_init(mis);
     avahi_start(mis);
+
+#ifdef HAVE_X11
+    if (settings->key_grabbing)
+           key_grabber_grab_keys(mis);
+#endif
 }
 
 void quit()
@@ -80,8 +86,13 @@
     g_main_loop_quit(loop);
 }
 
-void destroy()
+void destroy(settings_t* settings)
 {
+#ifdef HAVE_X11
+    if (settings->key_grabbing)
+           key_grabber_ungrab_keys(mis);
+#endif
+
     pulseaudio_destroy();
     avahi_destroy();
     menu_infos_destroy(mis);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/pasystray.gtk2.glade 
new/pasystray-0.8.0/src/pasystray.gtk2.glade
--- old/pasystray-pasystray-0.7.1/src/pasystray.gtk2.glade      2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/src/pasystray.gtk2.glade        2021-10-21 
20:54:40.000000000 +0200
@@ -2,32 +2,6 @@
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy toplevel-contextual -->
-  <object class="GtkAboutDialog" id="aboutdialog">
-    <property name="can_focus">False</property>
-    <property name="border_width">5</property>
-    <property name="icon_name">pasystray</property>
-    <property name="type_hint">dialog</property>
-    <property name="program_name">pasystray</property>
-    <property name="copyright" translatable="yes">Copyright ?? 
2011-2016</property>
-    <property name="comments" translatable="yes">PulseAudio system 
tray</property>
-    <property name="authors">Christoph Gysin 
&lt;christoph.gy...@gmail.com&gt;</property>
-    <property name="logo_icon_name">pasystray</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="aboutdialog-vbox">
-        <property name="can_focus">False</property>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="aboutdialog-action_area">
-            <property name="can_focus">True</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
   <object class="GtkMessageDialog" id="errordialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/pasystray.gtk3.glade 
new/pasystray-0.8.0/src/pasystray.gtk3.glade
--- old/pasystray-pasystray-0.7.1/src/pasystray.gtk3.glade      2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/src/pasystray.gtk3.glade        2021-10-21 
20:54:40.000000000 +0200
@@ -2,42 +2,6 @@
 <!-- Generated with glade 3.18.3 -->
 <interface>
   <requires lib="gtk+" version="3.0"/>
-  <object class="GtkAboutDialog" id="aboutdialog">
-    <property name="can_focus">False</property>
-    <property name="border_width">5</property>
-    <property name="icon_name">pasystray</property>
-    <property name="type_hint">dialog</property>
-    <property name="program_name">pasystray</property>
-    <property name="copyright" translatable="yes">Copyright ?? 
2011-2016</property>
-    <property name="comments" translatable="yes">PulseAudio system 
tray</property>
-    <property name="authors">Christoph Gysin 
&lt;christoph.gy...@gmail.com&gt;</property>
-    <property name="logo_icon_name">pasystray</property>
-    <property name="license_type">lgpl-2-1</property>
-    <child internal-child="vbox">
-      <object class="GtkBox" id="aboutdialog-vbox">
-        <property name="can_focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox" id="aboutdialog-action_area">
-            <property name="can_focus">True</property>
-            <property name="can_default">True</property>
-            <property name="has_default">True</property>
-            <property name="layout_style">end</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <placeholder/>
-        </child>
-      </object>
-    </child>
-  </object>
   <object class="GtkMessageDialog" id="errordialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/pulseaudio_action.c 
new/pasystray-0.8.0/src/pulseaudio_action.c
--- old/pasystray-pasystray-0.7.1/src/pulseaudio_action.c       2019-01-02 
19:15:05.000000000 +0100
+++ new/pasystray-0.8.0/src/pulseaudio_action.c 2021-10-21 20:54:40.000000000 
+0200
@@ -162,15 +162,15 @@
     /* increment/decrement in 2% steps */
     pa_cvolume* volume;
     if(inc < 0)
-        volume = pa_cvolume_dec(mii->volume, -inc * PA_VOLUME_NORM / 50);
+        volume = pa_cvolume_dec(mii->volume, -inc * PA_VOLUME_NORM / 100);
     else if(inc > 0)
     {
         int volume_max = mii->menu_info->menu_infos->settings.volume_max;
         if(volume_max > 0)
-            volume = pa_cvolume_inc_clamp(mii->volume, inc * PA_VOLUME_NORM / 
50,
+            volume = pa_cvolume_inc_clamp(mii->volume, inc * PA_VOLUME_NORM / 
100,
                     PA_VOLUME_NORM * volume_max / 100);
         else
-            volume = pa_cvolume_inc(mii->volume, inc * PA_VOLUME_NORM / 50);
+            volume = pa_cvolume_inc(mii->volume, inc * PA_VOLUME_NORM / 100);
     }
     else
         return;
@@ -276,11 +276,15 @@
                 menu_info_type_name(mii->menu_info->type), label);
     g_free(label);
 
-    gint volume = (mii->volume->values[0]*100+PA_VOLUME_NORM/2)/PA_VOLUME_NORM;
+    gint volume = 
(pa_cvolume_max(mii->volume)*100+PA_VOLUME_NORM/2)/PA_VOLUME_NORM;
+
+    int volume_max = mii->menu_info->menu_infos->settings.volume_max;
+    gint value = (volume_max > 0) ? volume * 100 / volume_max : volume;
+
     if(!mii->notify)
-        mii->notify = notify(msg, NULL, mii->icon, volume);
+        mii->notify = notify(msg, NULL, mii->icon, value);
     else
-        notify_update(mii->notify, msg, NULL, mii->icon, volume);
+        notify_update(mii->notify, msg, NULL, mii->icon, value);
 
     g_free(msg);
 }
@@ -361,5 +365,8 @@
 
 void pulseaudio_terminate(void)
 {
-    pa_operation_unref(pa_context_exit_daemon(context, NULL, NULL));
+    pa_operation* exit_op = pa_context_exit_daemon(context, NULL, NULL);
+    if (exit_op) {
+        pa_operation_unref(exit_op);
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/systray.c 
new/pasystray-0.8.0/src/systray.c
--- old/pasystray-pasystray-0.7.1/src/systray.c 2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/src/systray.c   2021-10-21 20:54:40.000000000 +0200
@@ -19,6 +19,7 @@
   USA.
 ***/
 
+#include <glib/gi18n.h>
 #include "systray.h"
 
 #include "pasystray.h"
@@ -28,6 +29,7 @@
 #include "systray_impl.h"
 
 static const char* COMMAND_PAMAN = "paman";
+static const char* COMMAND_PAEQUALIZER = "qpaeq";
 static const char* COMMAND_PAVUCONTROL = "pavucontrol";
 static const char* COMMAND_PAVUMETER = "pavumeter";
 static const char* COMMAND_PAVUMETER_REC = "pavumeter --record";
@@ -52,6 +54,7 @@
     systray_menu_add_separator(mis->menu);
 
     systray_menu_add_application(mis->menu, "_Manager...", NULL, 
COMMAND_PAMAN);
+    systray_menu_add_application(mis->menu, "_Equalizer...", NULL, 
COMMAND_PAEQUALIZER);
     systray_menu_add_application(mis->menu, "Volume _Control...", NULL, 
COMMAND_PAVUCONTROL);
     systray_menu_add_application(mis->menu, "Volume Meter (_Playback)...", 
NULL, COMMAND_PAVUMETER);
     systray_menu_add_application(mis->menu, "Volume Meter (_Recording)...", 
NULL, COMMAND_PAVUMETER_REC);
@@ -204,33 +207,14 @@
 
 GtkWidget* systray_add_item(GtkMenuShell* menu, const char* desc, const char* 
tooltip, const char* icon)
 {
-    GtkWidget* item = gtk_menu_item_new();
-
-#if GTK_VERSION_MAJOR == 2
-    GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
-#else
-    GtkWidget* hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-#endif
-    gtk_container_add(GTK_CONTAINER(item), hbox);
+    GtkWidget* item = gtk_image_menu_item_new_with_mnemonic(desc);
 
     if(icon)
     {
         GtkWidget* image = gtk_image_new_from_icon_name(icon, 
GTK_ICON_SIZE_MENU);
-#if GTK_VERSION_MAJOR == 2
-        gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
-#else
-        gtk_container_add(GTK_CONTAINER(hbox), image);
-#endif
+        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
     }
 
-    GtkWidget* label = gtk_label_new(NULL);
-    gtk_label_set_text_with_mnemonic(GTK_LABEL(label), desc);
-#if GTK_VERSION_MAJOR == 2
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
-#else
-    gtk_container_add(GTK_CONTAINER(hbox), label);
-#endif
-
     if(tooltip)
         systray_set_tooltip(item, tooltip);
 
@@ -346,9 +330,22 @@
 
 void systray_about_dialog()
 {
-    GtkDialog* dialog = ui_aboutdialog();
-    g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_hide), 
dialog);
-    gtk_widget_show_all(GTK_WIDGET(dialog));
+    char *authors[] = { _("Christoph Gysin <christoph.gy...@gmail.com>"),
+                        NULL };
+
+    gtk_show_about_dialog(NULL,
+                          "program-name", "pasystray",
+                          "version", PACKAGE_VERSION,
+                          "logo-icon-name", "pasystray",
+                          "comments", _("PulseAudio system tray"),
+                          "authors", authors,
+                          "copyright", _("Copyright ?? 2011-2016"),
+#if GTK_CHECK_VERSION(3,0,0)
+                          "license-type", GTK_LICENSE_LGPL_2_1,
+#endif
+                          "website", PACKAGE_URL,
+                          "website-label", PACKAGE_URL,
+                          NULL);
 }
 
 void systray_click_cb(GtkStatusIcon* icon, GdkEventButton* ev, gpointer 
userdata)
@@ -411,14 +408,15 @@
 void systray_scroll_cb(guint state, GdkScrollDirection direction, 
menu_infos_t* mis)
 {
     int inc = 0;
+    int reverse_factor = mis->settings.reverse_scroll ? -1 : 1;
 
     switch(direction)
     {
         case GDK_SCROLL_UP:
-            inc = mis->settings.volume_inc;
+            inc = reverse_factor * mis->settings.volume_inc;
             break;
         case GDK_SCROLL_DOWN:
-            inc = -mis->settings.volume_inc;
+            inc = reverse_factor * -mis->settings.volume_inc;
             break;
         default:
             return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/ui.c 
new/pasystray-0.8.0/src/ui.c
--- old/pasystray-pasystray-0.7.1/src/ui.c      2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/src/ui.c        2021-10-21 20:54:40.000000000 +0200
@@ -20,12 +20,42 @@
 ***/
 
 #include <glib.h>
+#include "menu_info.h"
 #include "ui.h"
 #include "config.h"
 #include "systray_impl.h"
 
+typedef enum {
+    ICON_IDX_MUTED = 0,
+    ICON_IDX_LOW = 1,
+    ICON_IDX_MEDIUM = 2,
+    ICON_IDX_HIGH = 3
+} icon_idx_t;
+
+enum { ICON_IDX_COUNT = 4 };
+
+typedef const gchar* icon_set_t[ICON_IDX_COUNT];
+
+static icon_set_t volume_icon_names = {
+    [ICON_IDX_MUTED] = "audio-volume-muted",
+    [ICON_IDX_LOW] = "audio-volume-low",
+    [ICON_IDX_MEDIUM] = "audio-volume-medium",
+    [ICON_IDX_HIGH] = "audio-volume-high"
+};
+
+static icon_set_t mic_icon_names = {
+    [ICON_IDX_MUTED] = "microphone-sensitivity-muted",
+    [ICON_IDX_LOW] = "microphone-sensitivity-low",
+    [ICON_IDX_MEDIUM] = "microphone-sensitivity-medium",
+    [ICON_IDX_HIGH] = "microphone-sensitivity-high"
+};
+
+static icon_set_t ui_icon_names[MENU_COUNT];
+
 static GtkBuilder* builder;
 
+static void ui_load_icons(void);
+
 void ui_load()
 {
     builder = gtk_builder_new();
@@ -50,6 +80,8 @@
     g_free(local_file);
     g_free(local_file_src);
 
+    ui_load_icons();
+
     if(!ret)
     {
         g_error("[ui] %s", error->message);
@@ -60,21 +92,23 @@
 {
     g_debug("pulseaudio_set_volume_icon(%s)", mii->name);
 
-    pa_volume_t volume = pa_cvolume_avg(mii->volume);
+    pa_volume_t volume = pa_cvolume_max(mii->volume);
 
     g_debug("volume:%u%s", volume, mii->mute ? " muted" : "");
 
     const char* icon_name = NULL;
+    icon_idx_t idx;
 
-    if(volume == PA_VOLUME_MUTED || mii->mute)
-        icon_name = "audio-volume-muted";
+    if(mii->mute)
+        idx = ICON_IDX_MUTED;
     else if(volume < (PA_VOLUME_NORM / 3))
-        icon_name = "audio-volume-low";
+        idx = ICON_IDX_LOW;
     else if(volume < (PA_VOLUME_NORM / 3 * 2))
-        icon_name = "audio-volume-medium";
+        idx = ICON_IDX_MEDIUM;
     else
-        icon_name = "audio-volume-high";
+        idx = ICON_IDX_HIGH;
 
+    icon_name = ui_icon_names[mii->menu_info->type][idx];
     g_free(mii->icon);
     mii->icon = g_strdup(icon_name);
 }
@@ -89,17 +123,6 @@
     systray_impl_set_icon(mis->systray, mii->icon);
 }
 
-GtkDialog* ui_aboutdialog()
-{
-    GtkAboutDialog* aboutdialog = (GtkAboutDialog*) 
gtk_builder_get_object(builder, "aboutdialog");
-
-    gtk_about_dialog_set_version(aboutdialog, PACKAGE_VERSION);
-    gtk_about_dialog_set_website(aboutdialog, PACKAGE_URL);
-    gtk_about_dialog_set_website_label(aboutdialog, PACKAGE_URL);
-
-    return GTK_DIALOG(aboutdialog);
-}
-
 GtkDialog* ui_renamedialog()
 {
     return (GtkDialog*) gtk_builder_get_object(builder, "renamedialog");
@@ -126,3 +149,24 @@
 
     return GTK_DIALOG(dialog);
 }
+
+static const gchar* ui_find_icon_name(GtkIconTheme* theme, const gchar* name, 
const gchar* fallback)
+{
+    const gchar* s = g_strdup_printf("%s-symbolic", name);
+    if(gtk_icon_theme_has_icon(theme, s))
+        return s;
+    g_free(s);
+    if(gtk_icon_theme_has_icon(theme, name))
+        return g_strdup(name);
+    return g_strdup(fallback);
+}
+
+static void ui_load_icons(void) {
+    GtkIconTheme* theme = gtk_icon_theme_get_default();
+    for(menu_type_t mt = 0; mt < MENU_COUNT; mt++) {
+        const gchar** preferred_names = (mt == MENU_SOURCE ? mic_icon_names : 
volume_icon_names);
+        for(icon_idx_t i = 0; i < ICON_IDX_COUNT; i++) {
+            ui_icon_names[mt][i] = ui_find_icon_name(theme, 
preferred_names[i], volume_icon_names[i]);
+        }
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/ui.h 
new/pasystray-0.8.0/src/ui.h
--- old/pasystray-pasystray-0.7.1/src/ui.h      2019-01-02 19:15:05.000000000 
+0100
+++ new/pasystray-0.8.0/src/ui.h        2021-10-21 20:54:40.000000000 +0200
@@ -28,7 +28,6 @@
 void ui_load();
 void ui_set_volume_icon(menu_info_item_t* mii);
 void ui_update_systray_icon(menu_info_item_t* mii);
-GtkDialog* ui_aboutdialog();
 GtkDialog* ui_renamedialog();
 GtkLabel* ui_renamedialog_label();
 GtkEntry* ui_renamedialog_entry();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/x11-key-grabber.c 
new/pasystray-0.8.0/src/x11-key-grabber.c
--- old/pasystray-pasystray-0.7.1/src/x11-key-grabber.c 1970-01-01 
01:00:00.000000000 +0100
+++ new/pasystray-0.8.0/src/x11-key-grabber.c   2021-10-21 20:54:40.000000000 
+0200
@@ -0,0 +1,247 @@
+/*
+ * This file is part of pa-applet.
+ *
+ * ?? 2012 Fernando Tarl?? Cardoso Lemos
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <glib.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#include <X11/Xlib.h>
+
+#include "x11-key-grabber.h"
+#include "pulseaudio_action.h"
+
+#define NUM_KEYS_TO_GRAB 4
+
+void volume_raise_cb(unsigned int state, menu_infos_t *mis)
+{
+    menu_info_t* mi = &mis->menu_info[(state & ControlMask) ? MENU_SOURCE : 
MENU_SINK];
+    menu_info_item_t* mii = menu_info_item_get_by_name(mi, mi->default_name);
+
+    g_debug("[key_grabber] %sXF86AudioRaiseVolume pressed\n", (state & 
ControlMask) ? "Ctrl-" : "");
+    if(mii)
+        pulseaudio_volume(mii, mis->settings.volume_inc);
+}
+
+void volume_lower_cb(unsigned int state, menu_infos_t *mis)
+{
+    menu_info_t* mi = &mis->menu_info[(state & ControlMask) ? MENU_SOURCE : 
MENU_SINK];
+    menu_info_item_t* mii = menu_info_item_get_by_name(mi, mi->default_name);
+
+    g_debug("[key_grabber] %sXF86AudioLowerVolume pressed\n", (state & 
ControlMask) ? "Ctrl-" : "");
+    if(mii)
+         pulseaudio_volume(mii, -mis->settings.volume_inc);
+}
+
+void volume_mute_cb(unsigned int state, menu_infos_t *mis) {
+    menu_info_t* mi = &mis->menu_info[(state & ControlMask) ? MENU_SOURCE : 
MENU_SINK];
+    menu_info_item_t* mii = menu_info_item_get_by_name(mi, mi->default_name);
+
+    g_debug("[key_grabber] %sXF86AudioMute pressed\n", (state & ControlMask) ? 
"Ctrl-" : "");
+    if(mii)
+        pulseaudio_toggle_mute(mii);
+}
+
+void mic_mute_cb(unsigned int state, menu_infos_t *mis) {
+    menu_info_t* mi = &mis->menu_info[MENU_SOURCE];
+    menu_info_item_t* mii = menu_info_item_get_by_name(mi, mi->default_name);
+
+    g_debug("[key_grabber] XF86AudioMicMute pressed\n");
+    if(mii)
+        pulseaudio_toggle_mute(mii);
+}
+
+static key_grabber_cb *grabbers[NUM_KEYS_TO_GRAB] = {
+    volume_raise_cb,
+    volume_lower_cb,
+    volume_mute_cb,
+    mic_mute_cb
+};
+
+static const char *keysym_names[NUM_KEYS_TO_GRAB] = {
+    "XF86AudioRaiseVolume",
+    "XF86AudioLowerVolume",
+    "XF86AudioMute",
+    "XF86AudioMicMute"
+};
+
+static KeyCode grabbed_keys[NUM_KEYS_TO_GRAB] = { 0, };
+
+static GdkFilterReturn filter_func(GdkXEvent *gdk_xevent, GdkEvent *event, 
gpointer data)
+{
+    // Skip events other than key presses
+    XEvent *xevent = (XEvent *)gdk_xevent;
+    if (xevent->type != KeyPress)
+        return GDK_FILTER_CONTINUE;
+
+    // Find a match for the key press
+    XKeyEvent *keyevent = (XKeyEvent *)xevent;
+    for (int i = 0; i < NUM_KEYS_TO_GRAB; ++i) {
+        if (keyevent->keycode == grabbed_keys[i]) {
+            if (grabbers[i] != NULL)
+                (*grabbers[i])(keyevent->state, data);
+            return GDK_FILTER_REMOVE;
+        }
+    }
+
+    // Continue processing this event
+    return GDK_FILTER_CONTINUE;
+}
+
+void key_grabber_grab_keys(menu_infos_t *mis)
+{
+    // Find the X11 display
+    GdkDisplay *gdkDisplay = gdk_display_get_default();
+    Display *dpy = GDK_DISPLAY_XDISPLAY(gdkDisplay);
+
+    // Resolve the keysym names into keycodes
+    for (int i = 0; i < NUM_KEYS_TO_GRAB; ++i) {
+        // Resolve the keysym name into a keysym first
+        KeySym keysym = XStringToKeysym(keysym_names[i]);
+        if (keysym == NoSymbol) {
+            g_printerr("Failed to resolve %s into a keysym\n", 
keysym_names[i]);
+            continue;
+        }
+
+        // Resolve the keysym into a keycode
+        grabbed_keys[i] = XKeysymToKeycode(dpy, keysym);
+        if (grabbed_keys[i] == 0) {
+            g_printerr("Failed to resolve %s into a keycode\n", 
keysym_names[i]);
+            continue;
+        }
+    }
+
+    int numScreens = 1;
+#if GDK_VERSION_CUR_STABLE < G_ENCODE_VERSION(3, 10)
+    numScreens = gdk_display_get_n_screens(gdkDisplay);
+#endif
+
+    // Grab the keys for all screens
+    for (int i = 0; i < numScreens; ++i) {
+#if GTK_CHECK_VERSION(3,20,0)
+        GdkScreen *screen = gdk_display_get_default_screen(gdkDisplay);
+#else
+        GdkScreen *screen = gdk_display_get_screen(gdkDisplay, i);
+#endif
+        if (screen == NULL)
+            continue;
+
+        // Find the X11 root window
+        GdkWindow *gdkRoot = gdk_screen_get_root_window(screen);
+        Window root = GDK_WINDOW_XID(gdkRoot);
+
+        for (int i = 0; i < NUM_KEYS_TO_GRAB; ++i) {
+            // Ignore the keys that we couldn't resolve
+            KeyCode keycode = grabbed_keys[i];
+            if (keycode == 0)
+                continue;
+
+            // Try to grab the keycodes with any modifiers
+#if GTK_CHECK_VERSION(3,22,0)
+            gdk_x11_display_error_trap_push(gdkDisplay);
+#else
+            gdk_error_trap_push();
+#endif
+            XGrabKey(dpy, keycode, AnyModifier, root, True, GrabModeAsync, 
GrabModeAsync);
+
+#if GTK_CHECK_VERSION(3,22,0)
+            gdk_display_flush(gdkDisplay);
+#else
+            gdk_flush();
+#endif
+
+            // Handle errors
+#if GTK_CHECK_VERSION(3,22,0)
+            if (gdk_x11_display_error_trap_pop(gdkDisplay))
+#else
+            if (gdk_error_trap_pop())
+#endif
+                g_printerr("Failed to grab %s\n", keysym_names[i]);
+        }
+
+        // Register for X events
+        gdk_window_add_filter(gdkRoot, filter_func, mis);
+    }
+}
+
+void key_grabber_ungrab_keys(menu_infos_t *mis)
+{
+    // Find the X11 display
+    GdkDisplay *gdkDisplay = gdk_display_get_default();
+    Display *dpy = GDK_DISPLAY_XDISPLAY(gdkDisplay);
+
+    int numScreens = 1;
+#if GDK_VERSION_CUR_STABLE < G_ENCODE_VERSION(3, 10)
+    numScreens = gdk_display_get_n_screens(gdkDisplay);
+#endif
+
+    // Ungrab the keys for all screens
+    for (int i = 0; i < numScreens; ++i) {
+#if GTK_CHECK_VERSION(3,20,0)
+        GdkScreen *screen = gdk_display_get_default_screen(gdkDisplay);
+#else
+        GdkScreen *screen = gdk_display_get_screen(gdkDisplay, i);
+#endif
+        if (screen == NULL)
+            continue;
+
+        // Find the X11 root window
+        GdkWindow *gdkRoot = gdk_screen_get_root_window(screen);
+        Window root = GDK_WINDOW_XID(gdkRoot);
+
+        for (int i = 0; i < NUM_KEYS_TO_GRAB; ++i) {
+            // Ignore the keys that we couldn't resolve
+            KeyCode keycode = grabbed_keys[i];
+            if (keycode == 0)
+                continue;
+
+            // Ungrab everything
+#if GTK_CHECK_VERSION(3,22,0)
+            gdk_x11_display_error_trap_push(gdkDisplay);
+#else
+            gdk_error_trap_push();
+#endif
+            XUngrabKey(dpy, keycode, AnyModifier, root);
+
+#if GTK_CHECK_VERSION(3,22,0)
+            gdk_display_flush(gdkDisplay);
+
+            if (gdk_x11_display_error_trap_pop(gdkDisplay))
+#else
+            gdk_flush();
+
+            if (gdk_error_trap_pop())
+#endif
+                g_printerr("Failed to ungrab %s\n", keysym_names[i]);
+        }
+
+        // Unregister for X events
+        gdk_window_remove_filter(gdkRoot, filter_func, mis);
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pasystray-pasystray-0.7.1/src/x11-key-grabber.h 
new/pasystray-0.8.0/src/x11-key-grabber.h
--- old/pasystray-pasystray-0.7.1/src/x11-key-grabber.h 1970-01-01 
01:00:00.000000000 +0100
+++ new/pasystray-0.8.0/src/x11-key-grabber.h   2021-10-21 20:54:40.000000000 
+0200
@@ -0,0 +1,47 @@
+/*
+ * This file is part of pa-applet.
+ *
+ * ?? 2012 Fernando Tarl?? Cardoso Lemos
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef KEY_GRABBER_H
+#define KEY_GRABBER_H
+
+#include <glib.h>
+
+#include "menu_info.h"
+
+typedef void (key_grabber_cb)(unsigned int, menu_infos_t *);
+
+void key_grabber_grab_keys(menu_infos_t *);
+void key_grabber_ungrab_keys(menu_infos_t *);
+void key_grabber_register_volume_raise_callback(key_grabber_cb cb);
+void key_grabber_register_volume_lower_callback(key_grabber_cb cb);
+void key_grabber_register_volume_mute_callback(key_grabber_cb cb);
+
+#endif

Reply via email to