diff --git a/0001-Xm-Screen-Add-_NET_WORKAREA-support.patch b/0001-Xm-Screen-Add-_NET_WORKAREA-support.patch new file mode 100644 index 0000000..6dc940c --- /dev/null +++ b/0001-Xm-Screen-Add-_NET_WORKAREA-support.patch @@ -0,0 +1,146 @@ +From 78a0cd5bdbe447bab807a09fae18d8a961366abc Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 16 Jun 2025 14:29:22 +0200 +Subject: [PATCH 1/2] Xm/Screen: Add _NET_WORKAREA support + +Add support for the extended window manager hint _NET_WORKAREA to +prevent Motif from placing its widgets outside of the geometry +advertised by the window manager. + +Support for _NET_WORKAREA depends on the Xinerama patches as it shares +the same logic. + +Signed-off-by: Olivier Fourdan +--- + lib/Xm/Screen.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 108 insertions(+) + +diff --git a/lib/Xm/Screen.c b/lib/Xm/Screen.c +index 44abcfb3..6269ffb3 100644 +--- a/lib/Xm/Screen.c ++++ b/lib/Xm/Screen.c +@@ -1517,6 +1517,113 @@ XmGetXmScreen( + return widget; + } + ++static int ++_XmScreenGetCurrentDesktop(Screen *screen) ++{ ++ static Atom XmA_NET_CURRENT_DESKTOP = None; ++ Atom type; ++ Display *dpy; ++ Window rootwindow; ++ int result = False; ++ int desktop = 0; ++ int format; ++ unsigned long lengthRtn; ++ unsigned long bytesAfter; ++ unsigned char *data; ++ ++ dpy = DisplayOfScreen(screen); ++ rootwindow = RootWindowOfScreen(screen); ++ ++ if (XmA_NET_CURRENT_DESKTOP == None) ++ XmA_NET_CURRENT_DESKTOP = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False); ++ ++ result =XGetWindowProperty(dpy, rootwindow, ++ XmA_NET_CURRENT_DESKTOP, ++ 0L, 100000L, False, XA_CARDINAL, ++ &type, &format, &lengthRtn, &bytesAfter, ++ &data); ++ ++ if (type == XA_CARDINAL) { ++ desktop = *(int *)data; ++ XFree(data); ++ } ++#ifdef DEBUG_XINERAMA ++ printf("Current desktop is %i\n", desktop); ++#endif /* DEBUG_XINERAMA */ ++ ++ return desktop; ++} ++ ++static void ++_XmCheckNetWorkarea( ++ Screen *screen, ++ Position *ret_x, ++ Position *ret_y, ++ Position *ret_max_x, ++ Position *ret_max_y ) ++{ ++ static Atom XmA_NET_WORKAREA = None; ++ Atom type; ++ Display *dpy; ++ Window rootwindow; ++ int result = False; ++ int desktop = 0; ++ int format; ++ unsigned long lengthRtn; ++ unsigned long bytesAfter; ++ unsigned char *data; ++ long *net_workarea; ++ ++ dpy = DisplayOfScreen(screen); ++ rootwindow = RootWindowOfScreen(screen); ++ desktop = _XmScreenGetCurrentDesktop(screen); ++ ++ if (XmA_NET_WORKAREA == None) ++ XmA_NET_WORKAREA = XInternAtom(dpy, "_NET_WORKAREA", False); ++ ++ result =XGetWindowProperty(dpy, rootwindow, ++ XmA_NET_WORKAREA, ++ 0L, 100000L, False, XA_CARDINAL, ++ &type, &format, &lengthRtn, &bytesAfter, ++ &data); ++ ++ if (result != Success || type != XA_CARDINAL || format != 32 || ++ bytesAfter != 0 || lengthRtn % 4 != 0 || desktop + 1 > lengthRtn / 4) ++ goto done; ++ ++ net_workarea = (long *) data; ++ ++#define NET_WORKAREA_X (desktop * 4) ++#define NET_WORKAREA_Y (desktop * 4 + 1) ++#define NET_WORKAREA_WIDTH (desktop * 4 + 2) ++#define NET_WORKAREA_HEIGHT (desktop * 4 + 3) ++ ++ if (*ret_x < net_workarea[NET_WORKAREA_X]) ++ *ret_x = net_workarea[NET_WORKAREA_X]; ++ ++ if (*ret_y < net_workarea[NET_WORKAREA_Y]) ++ *ret_y = net_workarea[NET_WORKAREA_Y]; ++ ++ if (*ret_max_x > net_workarea[NET_WORKAREA_X] + net_workarea[NET_WORKAREA_WIDTH]) ++ *ret_max_x = net_workarea[NET_WORKAREA_X] + net_workarea[NET_WORKAREA_WIDTH]; ++ ++ if (*ret_max_y > net_workarea[NET_WORKAREA_Y] + net_workarea[NET_WORKAREA_HEIGHT]) ++ *ret_max_y = net_workarea[NET_WORKAREA_Y] + net_workarea[NET_WORKAREA_HEIGHT]; ++ ++#undef NET_WORKAREA_X ++#undef NET_WORKAREA_Y ++#undef NET_WORKAREA_WIDTH ++#undef NET_WORKAREA_HEIGHT ++ ++#ifdef DEBUG_XINERAMA ++ printf("_NET_WORKAREA within (%i,%i) and (%i,%i)\n", *ret_x, *ret_y, *ret_max_x, *ret_max_y); ++#endif /* DEBUG_XINERAMA */ ++ ++done: ++ if (data) ++ XFree(data); ++} ++ + void + _XmScreenGetBoundariesAtpoint( + Screen *screen, +@@ -1561,6 +1668,7 @@ _XmScreenGetBoundariesAtpoint( + } + } + #endif /* HAVE_LIBXINERAMA */ ++ _XmCheckNetWorkarea(screen, &screen_x, &screen_y, &screen_max_x, &screen_max_y); + out: + #ifdef DEBUG_XINERAMA + printf("Point (%i,%i) constrained within (%i,%i) and (%i,%i)\n", +-- +2.50.0 + diff --git a/0002-Xm-Screen-Add-_GTK_WORKAREAS-support-for-multi-monit.patch b/0002-Xm-Screen-Add-_GTK_WORKAREAS-support-for-multi-monit.patch new file mode 100644 index 0000000..7726681 --- /dev/null +++ b/0002-Xm-Screen-Add-_GTK_WORKAREAS-support-for-multi-monit.patch @@ -0,0 +1,145 @@ +From 2f18ccbffee237845c0b3c2d745d20ac66748f8a Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Fri, 27 Jun 2025 12:11:41 +0200 +Subject: [PATCH 2/2] Xm/Screen: Add _GTK_WORKAREAS support for multi-monitor + +Add support for the GTK property _GTK_WORKAREAS to prevent Motif from +placing its widgets outside of the geometry advertised by the window +manager on a multi-monitor setup. + +Unlike the extended window manager hint _NET_WORKAREA which defines a +single rectangle for the whole screen spanning across all the monitors, +_GTK_WORKAREAS provides an area per monitor, making that property more +adequate on a multi-monitor setup. + +However, if _GTK_WORKAREAS is not supported, we fallback to the standard +_NET_WORKAREA property. + +Support for _GTK_WORKAREAS depends on the Xinerama patches as it shares +the same logic. + +Signed-off-by: Olivier Fourdan +--- + lib/Xm/Screen.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 91 insertions(+), 1 deletion(-) + +diff --git a/lib/Xm/Screen.c b/lib/Xm/Screen.c +index 6269ffb3..d8d24e9a 100644 +--- a/lib/Xm/Screen.c ++++ b/lib/Xm/Screen.c +@@ -1554,6 +1554,91 @@ _XmScreenGetCurrentDesktop(Screen *screen) + return desktop; + } + ++static Boolean ++_XmCheckGtkWorkareas( ++ Screen *screen, ++ Position pt_x, ++ Position pt_y, ++ Position *ret_x, ++ Position *ret_y, ++ Position *ret_max_x, ++ Position *ret_max_y ) ++{ ++ Atom XmA_GTK_WORKAREAS; ++ Atom type; ++ Display *dpy; ++ Window rootwindow; ++ int result = False; ++ int desktop = 0; ++ int format; ++ unsigned long lengthRtn; ++ unsigned long bytesAfter; ++ unsigned char *data; ++ long *gtk_workareas; ++ char atom_name[32]; ++ int monitor, n_monitors; ++ Position tmp_x, tmp_y; ++ Position tmp_max_x, tmp_max_y; ++ Boolean ret = False; ++ ++ dpy = DisplayOfScreen(screen); ++ rootwindow = RootWindowOfScreen(screen); ++ desktop = _XmScreenGetCurrentDesktop(screen); ++ ++ snprintf(atom_name, sizeof(atom_name), "_GTK_WORKAREAS_D%d", desktop); ++ XmA_GTK_WORKAREAS = XInternAtom(dpy, atom_name, False); ++ ++ result = XGetWindowProperty(dpy, rootwindow, ++ XmA_GTK_WORKAREAS, ++ 0L, 100000L, False, XA_CARDINAL, ++ &type, &format, &lengthRtn, &bytesAfter, ++ &data); ++ ++ if (result != Success || type != XA_CARDINAL || format != 32 || ++ bytesAfter != 0 || lengthRtn % 4 != 0) { ++ goto done; ++ } ++ ++ gtk_workareas = (long *) data; ++ n_monitors = lengthRtn / 4; ++ ++#define GTK_WORKAREA_X (monitor * 4) ++#define GTK_WORKAREA_Y (monitor * 4 + 1) ++#define GTK_WORKAREA_WIDTH (monitor * 4 + 2) ++#define GTK_WORKAREA_HEIGHT (monitor * 4 + 3) ++ ++ for (monitor = 0; monitor < n_monitors; ++monitor) { ++ tmp_x = gtk_workareas[GTK_WORKAREA_X]; ++ tmp_y = gtk_workareas[GTK_WORKAREA_Y]; ++ tmp_max_x = tmp_x + gtk_workareas[GTK_WORKAREA_WIDTH]; ++ tmp_max_y = tmp_y + gtk_workareas[GTK_WORKAREA_HEIGHT]; ++ ++ if (pt_x >= tmp_x && pt_x < tmp_max_x && pt_y >= tmp_y && pt_y < tmp_max_y) { ++ *ret_x = tmp_x; ++ *ret_y = tmp_y; ++ *ret_max_x = tmp_max_x; ++ *ret_max_y = tmp_max_y; ++ ret = True; ++ break; /* We have a match */ ++ } ++ } ++ ++#undef GTK_WORKAREA_X ++#undef GTK_WORKAREA_Y ++#undef GTK_WORKAREA_WIDTH ++#undef GTK_WORKAREA_HEIGHT ++ ++#ifdef DEBUG_XINERAMA ++ printf("Point (%i,%i) constrained by _GTK_WORKAREAS_D%d within (%i,%i) and (%i,%i)\n", ++ pt_x, pt_y, desktop, *ret_x, *ret_y, *ret_max_x, *ret_max_y); ++#endif /* DEBUG_XINERAMA */ ++ ++done: ++ if (data) ++ XFree(data); ++ return ret; ++} ++ + static void + _XmCheckNetWorkarea( + Screen *screen, +@@ -1637,6 +1722,7 @@ _XmScreenGetBoundariesAtpoint( + XmDisplay xmDisplay; + Position screen_x, screen_y; + Position screen_max_x, screen_max_y; ++ Boolean check_gtk_workarea; + #ifdef HAVE_LIBXINERAMA + Position tmp_x, tmp_y; + Position tmp_max_x, tmp_max_y; +@@ -1668,7 +1754,11 @@ _XmScreenGetBoundariesAtpoint( + } + } + #endif /* HAVE_LIBXINERAMA */ +- _XmCheckNetWorkarea(screen, &screen_x, &screen_y, &screen_max_x, &screen_max_y); ++ check_gtk_workarea = _XmCheckGtkWorkareas(screen, pt_x, pt_y, ++ &screen_x, &screen_y, ++ &screen_max_x, &screen_max_y); ++ if (!check_gtk_workarea) ++ _XmCheckNetWorkarea(screen, &screen_x, &screen_y, &screen_max_x, &screen_max_y); + out: + #ifdef DEBUG_XINERAMA + printf("Point (%i,%i) constrained within (%i,%i) and (%i,%i)\n", +-- +2.50.0 + diff --git a/motif.spec b/motif.spec index 3817f94..b653568 100644 --- a/motif.spec +++ b/motif.spec @@ -1,7 +1,7 @@ Summary: Run-time libraries and programs Name: motif Version: 2.3.4 -Release: 23%{?dist} +Release: 24%{?dist} License: LGPLv2+ Group: System Environment/Libraries Source: http://downloads.sf.net/motif/motif-%{version}-src.tgz @@ -54,9 +54,12 @@ Patch61: 0004-Xm-DropDown-Use-Xinerama-for-placement.patch Patch62: 0005-Xm-RCMenu-Use-Xinerama-for-placement.patch Patch63: 0006-Xm-Tooltip-Use-Xinerama-for-placement.patch Patch64: 0007-Xm-ComboBox-Use-Xinerama-for-placement.patch - # https://issues.redhat.com/browse/RHEL-96948 Patch65: 0001-Xm-String-Fix-memory-leak.patch +# https://issues.redhat.com/browse/RHEL-97048 +# (see also https://issues.redhat.com/browse/RHEL-87743) +Patch66: 0001-Xm-Screen-Add-_NET_WORKAREA-support.patch +Patch67: 0002-Xm-Screen-Add-_GTK_WORKAREAS-support-for-multi-monit.patch Conflicts: lesstif <= 0.92.32-6 @@ -116,6 +119,8 @@ This package contains the static Motif libraries. %patch63 -p1 -b .xinerama %patch64 -p1 -b .xinerama %patch65 -p1 -b .memleak +%patch66 -p1 -b .net_workarea +%patch67 -p1 -b .gtk_workareas %build CFLAGS="$RPM_OPT_FLAGS -D_FILE_OFFSET_BITS=64" \ @@ -173,6 +178,10 @@ rm -rf %{buildroot} %{_libdir}/lib*.a %changelog +* Fri Sep 5 2025 Olivier Fourdan - 2.3.4-24 +- Add support for _NET_WORKAREA and _GTK_WORKAREAS + Resolves: RHEL-97048 + * Fri Jun 27 2025 Olivier Fourdan - 2.3.4-23 - Fix a memory leak with UTF-8 strings Resolves: RHEL-96948