You are not logged in.
Hi!
I am new to this forum. I just found a weird behaviour which seems to me related to XFCE, but as other software is related I would not say 100% sure that it is an XFCE bug.
I am using Debian 11 with updated packages and, in particular, XFCE 4.16. I use often the shortcut Alt+Tab to switch among windows in a workspace, usually without problems.
The weird behaviour is when using LibreOffice Calc (I tested with versions 7.0.4.2 and 7.1.4.2). If I have the cursor on a cell, Alt+Tab seems to work fine, but if I place the cursor on the Find toolbar (by means of the touchpad or Ctrl+F), when next I use Alt+Tab to switch to another window, then in an abstract way the switch is done (sometimes)*, but the window in front is still LibreOffice Calc.
* I say that in an abstract way the switch is done (sometimes) because:
First, on the panel bar, among the shown tabs of open windows, the app marked is that I decided to switch with Alt+Tab (sometimes)
Moreover, after I have done the previous step, so 1) I was on LibreOffice Calc on Find Toolbar, but after 2) I switched window with Alt+Tab but I see yet LibreOffice Calc window, then, if 3) I use again Alt+Tab, this time the window that appears is the one I decide, so it works fine.
That happens sometimes, but other times, after using Alt+Tab to swich to another window, the app marked on the panel bar is yet LibreOffice Calc
NB: I tried to illustrate the first item of the list with an screenshot saved on Dropbox, but I couldn't get it previewed on this message. Let me know if I could be more specific, or if this issue happens also to you.
Thank you!
Iago
Last edited by Iago (2021-09-17 14:17:55)
Offline
Hello and welcome.
I can replicate this on my system as well. I'm not sure if this is a bug in xfwm4 or the libreoffice find dialog somehow interfering in the process. I'm leaning towards libreoffice as I can't replicate the problem with other find dialogs in the system.
Mark solved threads as [SOLVED] to make it easier for others to find solutions.
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
I can replicate this.
The LO community has been aware of this for a while:
https://bugs.documentfoundation.org/sho … ?id=156232
Reported to XFWM devs today:
https://gitlab.xfce.org/xfce/xfwm4/-/issues/863
Last edited by xfce-amateur (2025-05-26 13:47:01)
Offline
I have a workaround for this, a small app in C that monitors focus changes and raises the new active window when focus leaves a LibreOffice window,
ensuring the selected application comes to the top of the stacking order.
Requires libx11-dev
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
/* Compilation and execution instructions:
* gcc -o lo-focus-tracker lo_focus_tracker.c -lX11
* ./lo-focus-tracker
*/
/* Error handler to ignore BadWindow errors and prevent crashes */
int ignore_xerror(Display *dpy, XErrorEvent *error) {
if (error->error_code == BadWindow) {
return 0; // Silently ignore BadWindow errors (e.g., when a window is closed)
}
return 0;
}
/* Check if a window belongs to LibreOffice by inspecting its WM_CLASS */
bool is_libreoffice(Display *dpy, Window win) {
if (!win || win == None) return false; // Invalid or null window
XClassHint class_hint;
if (XGetClassHint(dpy, win, &class_hint)) { // Retrieve window's class hint
bool result = false;
if (class_hint.res_class) {
// Check if "libreoffice" is in the window's class name
result = strstr(class_hint.res_class, "libreoffice") != NULL;
}
// Free allocated memory for class hint
if (class_hint.res_name) XFree(class_hint.res_name);
if (class_hint.res_class) XFree(class_hint.res_class);
return result;
}
return false; // Failed to get class hint
}
/* Check if a window is minimized by inspecting _NET_WM_STATE */
bool is_minimized(Display *dpy, Window win) {
if (!win || win == None) return false; // Invalid or null window
// Get atoms for _NET_WM_STATE and _NET_WM_STATE_HIDDEN
Atom _NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", True);
Atom HIDDEN = XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", True);
Atom actual_type;
int format;
unsigned long nitems, bytes;
unsigned char *data = NULL;
// Retrieve window's _NET_WM_STATE property
if (XGetWindowProperty(dpy, win, _NET_WM_STATE, 0, (~0L), False,
XA_ATOM, &actual_type, &format, &nitems, &bytes, &data) == Success) {
if (data) {
Atom *atoms = (Atom *)data;
// Check if _NET_WM_STATE_HIDDEN is present
for (unsigned long i = 0; i < nitems; i++) {
if (atoms[i] == HIDDEN) {
XFree(data);
return true; // Window is minimized
}
}
XFree(data); // Free property data
}
}
return false; // Window is not minimized
}
/* Get the currently active window using _NET_ACTIVE_WINDOW */
Window get_active_window(Display *dpy) {
Atom actual_type;
int format;
unsigned long nitems, bytes;
unsigned char *data = NULL;
// Get atom for _NET_ACTIVE_WINDOW
Atom _NET_ACTIVE_WINDOW = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", True);
// Retrieve _NET_ACTIVE_WINDOW property from the root window
if (XGetWindowProperty(dpy, DefaultRootWindow(dpy),
_NET_ACTIVE_WINDOW, 0, (~0L), False, AnyPropertyType,
&actual_type, &format, &nitems, &bytes, &data) == Success) {
if (nitems > 0 && data != NULL) {
Window win = *(Window *)data; // Extract window ID
XFree(data); // Free property data
return win;
}
}
return None; // No active window found
}
/* Main program to monitor focus changes and raise new active windows */
int main() {
// Open connection to the X11 display
Display *dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "Cannot open display\n");
return 1; // Exit if display cannot be opened
}
// Set error handler to prevent crashes
XSetErrorHandler(ignore_xerror);
Window prev_active = None; // Track previously active window
// Main loop to monitor active window changes
while (1) {
Window current = get_active_window(dpy); // Get current active window
// Check if the active window has changed
if (current != prev_active) {
// Determine if current and previous windows are LibreOffice
bool current_is_lo = is_libreoffice(dpy, current);
bool prev_is_lo = (prev_active != None) && is_libreoffice(dpy, prev_active);
bool prev_is_minimized = (prev_active != None) && is_minimized(dpy, prev_active);
// Handle focus loss from a non-minimized LibreOffice window
if (prev_is_lo && !prev_is_minimized && current != prev_active) {
// Log focus change for debugging
printf("LibreOffice focus lost: 0x%lx → 0x%lx\n", prev_active, current);
// Optional: Uncomment to show a notification (requires notify-send)
//system("notify-send 'LibreOffice focus lost'");
// Workaround for xfwm4: Raise the new active window
if (current != None) {
XRaiseWindow(dpy, current); // Bring new window to the top
XFlush(dpy); // Ensure the raise command is sent
}
}
prev_active = current; // Update previous window
}
usleep(300000); // Sleep for 0.3 seconds to reduce CPU usage
}
// Close the display connection
XCloseDisplay(dpy);
return 0;
}
If you prefer this is a bash version which requires xdotool
#!/bin/bash
# Script to monitor LibreOffice window focus changes and ensure proper window activation
# Workaround for xfwm4 window cycling issue with LibreOffice (Xfce GitLab issue #864)
# Uses xdotool to track and activate windows when focus leaves or switches LibreOffice windows
# Initialize variables to track previous state
PREV_LO_WINDOW="" # ID of the previously focused LibreOffice window
PREV_LO_APP="" # Application name of the previous LibreOffice window
PREV_IN_FOCUS=false # Flag indicating if a LibreOffice window was last in focus
# Function to extract the LibreOffice application name from a window's WM_NAME
# Args:
# $1: Window ID
# Returns: The first word of the WM_NAME property (e.g., "Writer", "Calc")
get_lo_app_name() {
local win_id=$1
# Use xprop to get WM_NAME, extract the string, and take the first word
xprop -id "$win_id" WM_NAME 2>/dev/null | sed -n 's/.*= "\(.*\)".*/\1/p' | awk '{print $1}'
}
# Main loop to monitor window focus changes
while :
do
# Get the currently active and focused windows using xdotool
ACTIVE_WIN=$(xdotool getactivewindow 2>/dev/null) # ID of the active window
FOCUS_WIN=$(xdotool getwindowfocus 2>/dev/null) # ID of the focused window
# Get all visible LibreOffice windows (based on WM_CLASS "libreoffice")
LO_WINDOWS=$(xdotool search --onlyvisible --class libreoffice 2>/dev/null)
# Log current state for debugging
echo "-----------------------------"
printf "Active: 0x%08x\n" "$ACTIVE_WIN" # Print active window ID in hex
printf "Focus: 0x%08x\n" "$FOCUS_WIN" # Print focused window ID in hex
# Initialize variables for the current LibreOffice window
CURRENT_LO_WINDOW="" # ID of the current LibreOffice window (if any)
CURRENT_LO_APP="" # Application name of the current LibreOffice window
# Check if any LibreOffice window is active or focused
for win in $LO_WINDOWS; do
if [[ "$win" == "$ACTIVE_WIN" || "$win" == "$FOCUS_WIN" ]]; then
CURRENT_LO_WINDOW="$win" # Store matching window ID
CURRENT_LO_APP=$(get_lo_app_name "$win") # Get its application name
break # Exit loop after finding the first match
fi
done
# Handle focus transitions
if [ -n "$CURRENT_LO_WINDOW" ]; then
# A LibreOffice window is active or focused
if $PREV_IN_FOCUS && [ "$CURRENT_LO_WINDOW" != "$PREV_LO_WINDOW" ]; then
# Focus switched from one LibreOffice window to another
# Activate the new LibreOffice window to ensure it’s raised
xdotool windowactivate "$CURRENT_LO_WINDOW"
echo "Activated new LO window: 0x$CURRENT_LO_WINDOW"
fi
# Update state for the next iteration
PREV_IN_FOCUS=true
PREV_LO_WINDOW="$CURRENT_LO_WINDOW"
PREV_LO_APP="$CURRENT_LO_APP"
else
# No LibreOffice window is active or focused
if $PREV_IN_FOCUS; then
# Focus left a LibreOffice window; activate the new active window
xdotool windowactivate "$ACTIVE_WIN"
echo "Activated non-LO window: 0x$ACTIVE_WIN"
fi
# Reset state for non-LibreOffice focus
PREV_IN_FOCUS=false
PREV_LO_WINDOW=""
PREV_LO_APP=""
fi
# Print a blank line for readability
echo ""
# Sleep for 1 second to reduce CPU usage
sleep 1
done
While one of these is running it will raise the selected window on Alt+TAB even though find is open in Libre Office apps (e.g Writter, Calc).
Last edited by Misko_2083 (2025-06-03 17:34:49)
Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c
Offline
[ Generated in 0.013 seconds, 7 queries executed - Memory usage: 584.05 KiB (Peak: 600.89 KiB) ]