Package: lxpanel
Version: 0.10.1-4
Severity: important
Tags: patch
X-Debbugs-Cc: ChangZhuo Chen (陳昌倬) <czc...@debian.org>

There are a lot of issues with GTK3 version of lxpanel that makes it almost
unusable. The following patches required to apply to fix an issues:
 * 02-Correct-icon-grid-width-under-GTK3.-Fixes-Github-29.patch
 * 03-Correct-panel-size-under-GTK3.-Fixes-Sourceforge-773.patch
 * 04-Support-HiDPI-on-GTK-3.patch
 * 05-Highlight-selected-workspace-in-pager.patch
 * 06-fix-alsa-volume-issue.patch
 * 07-Fix-division-by-zero-with-broken-batteries.patch
 * 08-Use-XkbRF_GetNamesProp-instead-of-xkb_symbols.patch

This patches was taken from https://github.com/lxde-continued/lxpanel.git.
You may look there for more patches/details.

Mikhail Kshevetskiy

-- System Information:
Debian Release: trixie/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.5.0-1-amd64 (SMP w/8 CPU threads; PREEMPT)
Locale: LANG=ru_RU.UTF-8, LC_CTYPE=ru_RU.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages lxpanel depends on:
ii  libasound2           1.2.9-2
ii  libc6                2.37-8
ii  libcairo2            1.17.8-3
ii  libcurl3-gnutls      8.2.1-2
ii  libfm-gtk3-4         1.3.2-4
ii  libfm-modules        1.3.2-4
ii  libfm4               1.3.2-4
ii  libgdk-pixbuf-2.0-0  2.42.10+dfsg-1+b1
ii  libglib2.0-0         2.78.0-1
ii  libgtk-3-0           3.24.38-5
ii  libiw30              30~pre9-14
ii  libkeybinder-3.0-0   0.3.2-1.1
ii  libmenu-cache3       1.1.0-1.1
ii  libpango-1.0-0       1.51.0+ds-2
ii  libwnck-3-0          43.0-3
ii  libx11-6             2:1.8.6-1
ii  libxkbfile1          1:1.1.0-1
ii  libxml2              2.9.14+dfsg-1.3
ii  lxmenu-data          0.1.5-2.1
ii  lxpanel-data         0.10.1-4

Versions of packages lxpanel recommends:
ii  foot [x-terminal-emulator]                      1.15.3-1
ii  gnome-flashback [notification-daemon]           3.49.1-1+b1
ii  gnome-shell [notification-daemon]               44.4-1
ii  gnome-terminal [x-terminal-emulator]            3.49.99-1
ii  konsole [x-terminal-emulator]                   4:22.12.3-1
ii  libnotify-bin                                   0.8.2-1
ii  mate-notification-daemon [notification-daemon]  1.26.0-1
ii  mate-terminal [x-terminal-emulator]             1.26.1-1
ii  pavucontrol                                     5.0-2
ii  plasma-workspace [notification-daemon]          4:5.27.7-2
ii  xfce4-notifyd [notification-daemon]             0.8.2-1
ii  xfce4-terminal [x-terminal-emulator]            1.1.0-1
ii  xkb-data                                        2.38-2
ii  xterm [x-terminal-emulator]                     384-1

Versions of packages lxpanel suggests:
ii  dillo [www-browser]        3.0.5-7+b1
ii  firefox-esr [www-browser]  115.2.0esr-1
ii  konqueror [www-browser]    4:22.12.3-2
ii  links [www-browser]        2.29-1
ii  lynx [www-browser]         2.9.0dev.12-1

-- no debconf information
>From 3c1ad6bc7c8b4b3ba66c04e6e10aa741f028ba75 Mon Sep 17 00:00:00 2001
From: Ben Walsh <b...@wumpster.com>
Date: Mon, 7 Feb 2022 07:02:05 +0000
Subject: [PATCH] Correct icon-grid width under GTK3. Fixes Github #29.

---
 src/icon-grid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/icon-grid.c b/src/icon-grid.c
index 2177971e..5948fee6 100644
--- a/src/icon-grid.c
+++ b/src/icon-grid.c
@@ -392,7 +392,7 @@ static void panel_icon_grid_get_preferred_width(GtkWidget *widget,
     }
     panel_icon_grid_size_request(widget, &requisition);
     if (minimal_width)
-        *minimal_width = requisition.width;
+        *minimal_width = ig->constrain_width ? 2 : requisition.width;
     if (natural_width)
         *natural_width = requisition.width;
 }
-- 
2.40.1

>From 12576de7b83c634437217e23d74954070a1be2d5 Mon Sep 17 00:00:00 2001
From: Ben Walsh <b...@wumpster.com>
Date: Sat, 6 Jun 2020 10:38:15 +0100
Subject: [PATCH] Correct panel size under GTK3. Fixes Sourceforge #773.

---
 src/panel.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/panel.c b/src/panel.c
index 45188dbe..2b5fc9be 100644
--- a/src/panel.c
+++ b/src/panel.c
@@ -293,6 +293,12 @@ lxpanel_get_preferred_height (GtkWidget *widget,
   if (natural_height)
       *natural_height = requisition.height;
 }
+
+static GtkSizeRequestMode
+lxpanel_get_request_mode (GtkWidget *widget)
+{
+    return GTK_SIZE_REQUEST_CONSTANT_SIZE;
+}
 #endif
 
 static void lxpanel_size_allocate(GtkWidget *widget, GtkAllocation *a)
@@ -413,6 +419,7 @@ static void lxpanel_class_init(PanelToplevelClass *klass)
 #if GTK_CHECK_VERSION(3, 0, 0)
     widget_class->get_preferred_width = lxpanel_get_preferred_width;
     widget_class->get_preferred_height = lxpanel_get_preferred_height;
+    widget_class->get_request_mode = lxpanel_get_request_mode;
 #else
     widget_class->size_request = lxpanel_size_request;
 #endif
-- 
2.40.1

>From cddf60a71ac509a8b01c45e3b428e0e4ccb193fe Mon Sep 17 00:00:00 2001
From: Luke Shumaker <luke...@lukeshu.com>
Date: Sun, 5 May 2019 17:40:11 -0400
Subject: [PATCH 3/7] Support HiDPI on GTK+ 3

For the most part, GDK 3 magically takes care of HiDPI support for us,
scaling between application-pixels and device-pixels.  But when we speak
directly to the X server (as when we set `_NET_WM_STRUT_PARTIAL`), this
translation doesn't happen for us.  So scale the numbers we send to the X
server by the GDK scale_factor.

Without this, lxpanel (with `--enable-gtk3`) properly renders at HiDPI
(assuming GDK_SCALE is configured correctly), but doesn't reserve
enough space at the edge of the screen.

Signed-off-by: Vadim Ushakov <wandrien....@gmail.com>
---
 src/panel.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/panel.c b/src/panel.c
index 2b5fc9b..12e8c5a 100644
--- a/src/panel.c
+++ b/src/panel.c
@@ -674,9 +674,14 @@ void _panel_set_wm_strut(LXPanel *panel)
     if (p->setstrut &&
         _panel_edge_can_strut(panel, p->edge, p->monitor, &strut_size))
     {
-        desired_strut[index] = strut_size;
-        desired_strut[4 + index * 2] = strut_lower;
-        desired_strut[5 + index * 2] = strut_upper - 1;
+#if GTK_CHECK_VERSION(3, 10, 0)
+        gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(panel));
+#else
+        gint scale_factor = 1;
+#endif
+        desired_strut[index] = strut_size * scale_factor;
+        desired_strut[4 + index * 2] = strut_lower * scale_factor;
+        desired_strut[5 + index * 2] = (strut_upper - 1) * scale_factor;
     }
     else
     {
-- 
2.40.1

>From 585b702b139ee62d2a618959e440652e7c65ff75 Mon Sep 17 00:00:00 2001
From: Vadim Ushakov <wandrien....@gmail.com>
Date: Thu, 11 May 2023 15:08:40 +0700
Subject: [PATCH 4/7] Highlight selected workspace in pager

Apply patch http://sophie.zarb.org/rpms/9d697fa6536295e90f166ca7199d7850/files/10
---
 plugins/pager.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/plugins/pager.c b/plugins/pager.c
index fb560c2..8e9d457 100644
--- a/plugins/pager.c
+++ b/plugins/pager.c
@@ -91,6 +91,35 @@ static gboolean on_scroll_event(GtkWidget * p, GdkEventScroll * ev, LXPanel *pan
     return TRUE;
 }
 
+#if GTK_CHECK_VERSION(3, 0, 0)
+static void on_style_updated(GtkWidget *p, LXPanel *panel)
+{
+    PagerData *d = lxpanel_plugin_get_data(p);
+    GtkStyleContext *context = gtk_widget_get_style_context(d->pager);
+    GtkCssProvider *provider = gtk_css_provider_new();
+    GdkRGBA color;
+    gchar *color_str;
+    gchar *bg_css;
+
+    gtk_style_context_add_class(context, "wnck-pager");
+    /* Provide a fallback color for the highlighted workspace based on the current theme */
+    gtk_style_context_lookup_color(context, "theme_selected_bg_color", &color);
+    color_str = gdk_rgba_to_string(&color);
+    bg_css = g_strconcat(".wnck-pager:selected {\n"
+                         "	background-color:", color_str, ";\n"
+                         "}", NULL);
+    gtk_css_provider_load_from_data(provider, bg_css, -1, NULL);
+    g_free(bg_css);
+    g_free(color_str);
+
+    gtk_style_context_add_provider(context,
+                                   GTK_STYLE_PROVIDER(provider),
+                                   GTK_STYLE_PROVIDER_PRIORITY_FALLBACK);
+
+    g_object_unref(provider);
+}
+#endif
+
 static GtkWidget *pager_constructor(LXPanel *panel, config_setting_t *settings)
 {
     GtkWidget *p, *w;
@@ -115,6 +144,11 @@ static GtkWidget *pager_constructor(LXPanel *panel, config_setting_t *settings)
     g_signal_connect(p, "realize", G_CALLBACK(on_realize), panel);
     g_signal_connect(p, "size-allocate", G_CALLBACK(on_size_allocate), panel);
     g_signal_connect(p, "scroll-event", G_CALLBACK(on_scroll_event), panel);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    g_signal_connect(p, "style-updated", G_CALLBACK(on_style_updated), panel);
+#endif
+
     wnck_pager_set_display_mode(d->pager, WNCK_PAGER_DISPLAY_CONTENT);
 
     gtk_widget_show(w);
-- 
2.40.1

>From 5887516e73213b93f0c40eb6839e20cfd77af9d2 Mon Sep 17 00:00:00 2001
From: Salguero Nicolas <nico...@phenix.salguero.fr>
Date: Wed, 20 Jul 2022 09:16:17 +0200
Subject: [PATCH 6/7] Fix issue #45

---
 plugins/volumealsa/volumealsa.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/plugins/volumealsa/volumealsa.c b/plugins/volumealsa/volumealsa.c
index 5c41051..b644908 100644
--- a/plugins/volumealsa/volumealsa.c
+++ b/plugins/volumealsa/volumealsa.c
@@ -796,6 +796,17 @@ static void volumealsa_popup_scale_scrolled(GtkScale * scale, GdkEventScroll * e
     /* Dispatch on scroll direction to update the value. */
     if ((evt->direction == GDK_SCROLL_UP) || (evt->direction == GDK_SCROLL_LEFT))
         val += 2;
+#if GTK_CHECK_VERSION(3, 0, 0)
+    else if (evt->direction == GDK_SCROLL_SMOOTH)
+    {
+        gdouble delta_x, delta_y;
+        gdk_event_get_scroll_deltas(evt, &delta_x, &delta_y);
+        if ((delta_x < 0) || (delta_y < 0))
+            val += 2;
+        else
+            val -= 2;
+    }
+#endif
     else
         val -= 2;
 
@@ -972,6 +983,9 @@ static GtkWidget *volumealsa_constructor(LXPanel *panel, config_setting_t *setti
     /* Allocate top level widget and set into Plugin widget pointer. */
     vol->panel = panel;
     vol->plugin = p = gtk_event_box_new();
+#if GTK_CHECK_VERSION(3, 0, 0)
+    gtk_widget_add_events(p, GDK_SCROLL_MASK);
+#endif
     vol->settings = settings;
     lxpanel_plugin_set_data(p, vol, volumealsa_destructor);
     gtk_widget_set_tooltip_text(p, _("Volume control"));
-- 
2.40.1

>From 42beb532cbb7964f5db0564e60fe4f3feec0353b Mon Sep 17 00:00:00 2001
From: Vadim Ushakov <wandrien....@gmail.com>
Date: Wed, 10 May 2023 21:51:41 +0700
Subject: [PATCH 7/7] Fix division by zero with broken batteries

Fixes issue https://sourceforge.net/p/lxde/bugs/908/
---
 plugins/batt/batt_sys.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/plugins/batt/batt_sys.c b/plugins/batt/batt_sys.c
index 5a40273..8408f37 100644
--- a/plugins/batt/batt_sys.c
+++ b/plugins/batt/batt_sys.c
@@ -254,10 +254,9 @@ battery* battery_update(battery *b)
             b->current_now = b->power_now * 1000 / b->voltage_now;
     }
 #endif
-
-    if (b->charge_now != -1 && b->charge_full != -1)
+    if (b->charge_now != -1 && b->charge_full > 0)
         promille = (b->charge_now * 1000) / b->charge_full;
-    else if (b->energy_full != -1 && b->energy_now != -1)
+    else if (b->energy_now != -1 && b->energy_full > 0)
         /* no charge data, let try energy instead */
         promille = (b->energy_now * 1000) / b->energy_full;
     else {
-- 
2.40.1

>From ed603611a341d1d71dbaf7efc0f7031e2d42e622 Mon Sep 17 00:00:00 2001
From: Vadim Ushakov <wandrien....@gmail.com>
Date: Wed, 10 May 2023 17:11:31 +0700
Subject: [PATCH 5/7] Use XkbRF_GetNamesProp instead of xkb_symbols

Fixes https://github.com/lxde/lxpanel/issues/51

Based on https://github.com/mcz/lxpanel/commit/30d5b8d40049d344044549d3dd95191c3f55f801
---
 configure.ac        |   6 +++
 plugins/Makefile.am |   4 +-
 plugins/xkb/xkb.c   | 101 +++++++++++++++++++++++++++++++++++++++++++-
 plugins/xkb/xkb.h   |   2 +-
 4 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2d7e8e1..c525c74 100644
--- a/configure.ac
+++ b/configure.ac
@@ -323,6 +323,12 @@ AC_SUBST(LIBXML2_CFLAGS)
 AC_SUBST(LIBXML2_LIBS)
 fi
 
+# xkb
+if test x"$plugin_xkb" != "x"; then
+PKG_CHECK_MODULES([XKB], [xkbfile])
+AC_SUBST(XKB_LIBS)
+fi
+
 # Checks for header files.
 AC_PATH_X
 AC_HEADER_STDC
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index f179b06..611ce54 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -163,7 +163,9 @@ xkb_la_CFLAGS = \
 xkb_la_SOURCES = \
 	xkb/xkb-plugin.c \
 	xkb/xkb.c
-xkb_la_LIBADD = $(X11_LIBS)
+xkb_la_LIBADD = \
+	$(X11_LIBS) \
+	$(XKB_LIBS)
 
 xkeyboardconfigdir=$(datadir)/lxpanel/xkeyboardconfig
 xkeyboardconfig_DATA = \
diff --git a/plugins/xkb/xkb.c b/plugins/xkb/xkb.c
index 35a1e1b..b34ea67 100644
--- a/plugins/xkb/xkb.c
+++ b/plugins/xkb/xkb.c
@@ -33,6 +33,7 @@
 #include <string.h>
 
 #include <X11/XKBlib.h>
+#include <X11/extensions/XKBrules.h>
 
 #include <gtk/gtk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
@@ -121,6 +122,21 @@ static void refresh_group_xkb(XkbPlugin * xkb)
     xkb->current_group_xkb_no = xkb_state.group & (XkbNumKbdGroups - 1);
 }
 
+/*
+FIXME: delete in the future
+
+2023.05:
+
+Fix for issue https://github.com/lxde/lxpanel/issues/51
+based on https://github.com/mcz/lxpanel/commit/30d5b8d40049d344044549d3dd95191c3f55f801
+
+initialize_keyboard_description__old_way() should be removed, if no regressions
+are reported over the next few releases.
+
+*/
+
+/* TO BE REMOVED: BEGIN */
+
 static int exists_by_prefix(char * const *arr, int length, const char *sample, int prefix_length)
 {
     int i;
@@ -132,13 +148,14 @@ static int exists_by_prefix(char * const *arr, int length, const char *sample, i
     return 0;
 }
 
-/* Initialize the keyboard description initially or after a NewKeyboard event. */
-static int initialize_keyboard_description(XkbPlugin * xkb)
+static int initialize_keyboard_description__old_way(XkbPlugin * xkb)
 {
     /* Allocate a keyboard description. */
     XkbDescRec * xkb_desc = XkbAllocKeyboard();
     if (xkb_desc == NULL)
+    {
         g_warning("XkbAllocKeyboard failed\n");
+    }
     else
     {
         /* Read necessary values into the keyboard description. */
@@ -243,6 +260,86 @@ static int initialize_keyboard_description(XkbPlugin * xkb)
         }
         XkbFreeKeyboard(xkb_desc, 0, True);
     }
+}
+
+/* TO BE REMOVED: END */
+
+static int initialize_keyboard_description__new_way(XkbPlugin * xkb)
+{
+    /* Allocate a keyboard description. */
+    XkbDescRec * xkb_desc = XkbAllocKeyboard();
+    if (xkb_desc == NULL)
+    {
+        g_warning("XkbAllocKeyboard failed\n");
+        goto ikd_clean;
+    }
+
+    /* Read necessary values into the keyboard description. */
+    Display *xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+    XkbGetNames(xdisplay, XkbGroupNamesMask, xkb_desc);
+    if ((xkb_desc->names == NULL) || (xkb_desc->names->groups == NULL))
+    {
+        g_warning("XkbGetNames failed\n");
+        goto ikd_clean;
+    }
+
+    /* Get the group name of each keyboard layout. Infer the group count from the highest available. */
+    Atom * group_source = xkb_desc->names->groups;
+    int i;
+    for (i = 0; i < XkbNumKbdGroups; ++i)
+    {
+        g_free(xkb->group_names[i]);
+        xkb->group_names[i] = NULL;
+        if (group_source[i] != None)
+        {
+            xkb->group_count = i + 1;
+            char * p = XGetAtomName(xdisplay, group_source[i]);
+            xkb->group_names[i] = g_strdup(p);
+            XFree(p);
+        }
+    }
+    ikd_clean:
+    XkbFreeKeyboard(xkb_desc, 0, True);
+
+    /* Reinitialize the symbol name storage. */
+    XkbRF_VarDefsRec vd;
+    XkbRF_GetNamesProp(xdisplay, NULL, &vd);
+    for (i = 0; i < XkbNumKbdGroups; ++i)
+    {
+        g_free(xkb->symbol_names[i]);
+        xkb->symbol_names[i] = NULL;
+    }
+    char **symbol_source = g_strsplit(vd.layout, ",", 4);
+    for (i = 0; symbol_source[i]; ++i)
+    {
+        char * source = symbol_source[i];
+        gssize len = -1;
+        {
+            /*
+                Handle cases:
+                    * us:2
+                    * us(basic)
+                Truncate the string by '(', ':'.
+            */
+            char * separator = strpbrk(source, "(:");
+            if (separator)
+                len = separator - source;
+        }
+        xkb->symbol_names[i] = g_ascii_strup(source, len);
+    }
+    g_strfreev(symbol_source);
+}
+
+
+/* Initialize the keyboard description initially or after a NewKeyboard event. */
+static int initialize_keyboard_description(XkbPlugin * xkb)
+{
+    const gchar * use_fallback = g_getenv("LXPANEL_XKB_ISSUE_51_USE_FALLBACK");
+
+    if (g_strcmp0(use_fallback, "1") == 0)
+        initialize_keyboard_description__old_way(xkb);
+    else
+        initialize_keyboard_description__new_way(xkb);
 
     /* Ensure that all elements within the name vectors are initialized. */
     int i;
diff --git a/plugins/xkb/xkb.h b/plugins/xkb/xkb.h
index e6ca4f7..2bc92df 100644
--- a/plugins/xkb/xkb.h
+++ b/plugins/xkb/xkb.h
@@ -77,7 +77,7 @@ typedef struct {
 
 } XkbPlugin;
 
-#define MAX_MARKUP_LEN  64
+#define MAX_MARKUP_LEN  512 /*  FIXME: get rid of hardcoded sizes! */
 #define MAX_ROW_LEN  64
 
 extern void xkb_redraw(XkbPlugin * xkb);
-- 
2.40.1

Reply via email to