You are not logged in.
I looked at the code in panel.cpp, and the code uses the "viewport"'s width and height in multiple places. So I agree with your proposal that GetPrimaryViewport() should have this extra check to make sure that even the fallback's width/height aren't 0. ![]()
The only suggestion I have left is to print/log a warning msg that the viewport's width or height is unexpectedly 0, so anyone troubleshooting will have a good clue that DisplayWidth() and/or DisplayHeight() returned a bad value.
I went through the xfdesktop code looking for any place that calls g_object_get_qdata(), and there's only one place where it gets called while changing the desktop background: xfdesktop-background-manager.c, get_or_create_monitor().
But when I debugged through this code logic, there are several error checks earlier that apparently passed. For example, the code asks the Xfce Window Manager for a list of monitors currently connected, and that must have succeeded, because you didn't see any errors related to this check in your output. Then the code checks if the first monitor really is a monitor object, and that check ALSO passes. So if these checks are passing, I have absolutely no clue what could be causing those assertion failures that you posted. And since I can't reproduce the problem on my end, I'm out of ideas for what to do next.
I tried to compare this file to Dadealus xfdesktop to see what changes have been made. But this file doesn't even exist. So this is all new code. I learned the hard way that Excalibur's Xfce 4.20 has a lot of changes from Daedalus Xfce 4.18 involving detecting monitors, because I ran into my own problems with Excalibur Xfce's desktop when no monitor is connected. I was using VNC to remotely access the PC. So it's very likely that this new monitor code is causing problems for you.
In case you're curious, these were the two bugs I filed at debian.org.
When no monitor is connected, xfdesktop-settings shows two error messages
Another thought just hit me. The desktop settings app must be a different app from the app responsible for the desktop background. So it's possible that the problem isn't on the desktop settings app side, but on the desktop background app side. So give this a try:
- Open a terminal and run xfdesktop -Q. This should terminate the Xfce app responsible for the desktop background.
- Now run xfdesktop -e. This will start a new instance of the Xfce desktop background app, with debug messages enabled.
- Applications -> Settings -> Desktop, then change the background.
- Check the xfdesktop's console output for any clues.
- To stop the xfdesktop in the terminal, CTRL+C.
- To restore the Xfce desktop app to its running state, the easiest way is to log out, then log in again.
Well, I'm stumped. I got the exact same output you did, except for the difference in file names, and except that my background DID change. I have a fresh Excalibur install.
The only clue that I thought I had was the last line: "stop_image_loading(): xfdesktop_settings_stop_image_loading". But I see now that this line is printed when you close the dialog. So that's not a clue.
My next suggestions are wild and potentially risky, but I'll suggest them anyway in case you know how to recover from them. If you're not sure about the risk, don't try them.
* Try a different user
- Create a new user account.
- I forgot how to do this in Linux. I vaguely remember using the command "useradd", or was it "adduser"? I also forgot how to delete the user account after the test. You'll have to look these up.
- Log in with the new user account.
- Try changing the background.
- If this works, this suggests that there's a Xfce setting specific to your user account that's preventing the background from being changed.
- If this does NOT work, then I'm out of ideas.
* Try renaming your xfce4 directories
On my Excalibur PC, when I search for "xfce" in my home directory, I see two of them: one in ~/.cache/xfce4, the other in ~/.config/xfce4. The test is to rename them to something else, so you'll start fresh.
- Log out of Xfce, so there's no Xfce environment running.
- Switch to a TTY terminal. Log in. CTRL+ALT+F1.
- Rename each directory.
mv ~/.cache/xfce4 ~/.cache/xfce4_orig
mv ~/.config/xfce4 ~/.config/xfce4_orig- Go back to the login GUI and log in: CTRL+ALT+F7
- Try changing the background.
- If this works, then something in your .cache/xfce4 or .config/xfce4 was causing the problem. You can narrow down the problem by renaming the directories back, then rename one subdirectory at a time until you find which file causes the problem.
- If this does NOT work, then I'm out of ideas.
Edit: One other clue I can give you is that when I change the background, the new background file path is stored in ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml. Maybe that's a clue to help you narrow down your problem.
Try looking for error messages for clues:
- Close any Desktop Settings app that's running.
- Open a terminal and run tail -f ~/.xsession-errors. This will monitor this errors file and print out any new messages as they're appended. To stop this at any time, CTRL+C.
- While that's running, open another terminal and run xfdesktop-settings -e. The -e enables the debug messages output.
- Try changing the background image.
- Check both terminals for any clues about what went wrong.
It just occurred to me that all of the problems that I saw with auto_login (yes) + default_user (bad name) is due to the PAM library's error handling not behaving as described in the man pages, and not due to any coding problems in slim. Is PAM known to be problematic? Perhaps a better long term solution is for someone to go into PAM to find out what's actually going on with its error handling?
For the slim crash caused by auto_login (yes) + default_user (bad name), I've confirmed that the cause is the same in both Daedalus slim and "unstable" slim.
Slim did not actually crash. Instead, it intentionally exit() the app because it caught a PAM exception that it thought was too serious to continue.
* Where the exit() is occurring
The exit() occurs in App::Login() when the code tries to open a PAM session. Here's a condensed version of the code:
try{
pam.open_session();
}
catch(PAM::Cred_Exception& e){
/* Credentials couldn't be established */
return;
}
catch(PAM::Exception& e){
exit(ERR_EXIT);
}There are two error handling paths. The "Cred_Exception" path is considered "non-fatal" and returns control to the caller. The "Exception" path is considered "fatal" and will exit the app.
* Initial explanation
The Exception is thrown from Authenticator::open_session. Here's a condensed version:
void Authenticator::open_session(void)
{
switch ((last_result=pam_setcred(pam_handle, PAM_ESTABLISH_CRED)))
{
default:
case PAM_CRED_ERR:
case PAM_CRED_UNAVAIL:
throw Exception(pam_handle, "pam_setcred()", last_result);
case PAM_ACCT_EXPIRED:
case PAM_PERM_DENIED:
case PAM_CRED_EXPIRED:
case PAM_USER_UNKNOWN:
throw Cred_Exception(pam_handle, "pam_setcred()", last_result);
case PAM_SUCCESS:
break;
}
switch ((last_result=pam_open_session(pam_handle, 0)))
{
default:
throw Exception(pam_handle, "pam_open_session()", last_result);
case PAM_SUCCESS:
break;
}
return;
}The code makes a call to pam_setcred() and pam_open_session(). For the pam_setcred() error handling, the code treats some errors as fatal, while others are non-fatal, including PAM_USER_UNKNOWN, which is the situation we're testing. Looking at the pam_setcred() man page, PAM_USER_UNKNOWN is a possible return value.
For pam_open_session(), all errors are fatal errors. Look at the pam_open_session() man page, there are only a few errors that can be returned.
But even though the code looks good, what happens is that for a bad user name, pam_setcred() does NOT return PAM_USER_UNKNOWN, or any other error code! Instead, pam_open_session() DOES return PAM_USER_UNKNOWN, even though that's not a documented return code. PAM_USER_UNKNOWN is treated as a fatal exception, causing slim to exit.
* Root cause
During my debugging, I found out that a manual login using the slim GUI doesn't have these problems because the code doesn't even try to go through the App::Login() code. Instead the code validates the user/password FIRST, and THEN goes into the login process. So I wondered why the autologin doesn't try to validate the user name first.
I just discovered that the slim's autologin code DID try to validate the user name first. There's even a comment in the Auth_Exception error handling that describes the possibility of a bad user name. Here's the condensed code:
if (autologin)
{
try {
pam.check_acct();
Login(true);
}
catch(PAM::Auth_Exception& e){
// The default user is invalid
}
}So the entire mess with Authenticator::open_session() could have been avoided. So why didn't Authenticator::check_acct() throw an Auth_Exception that would have skipped the auto login attempt on a bad user name?
void Authenticator::check_acct(void)
{
switch((last_result=pam_acct_mgmt(pam_handle, PAM_SILENT)))
{
case PAM_ACCT_EXPIRED:
case PAM_USER_UNKNOWN:
case PAM_PERM_DENIED:
throw Auth_Exception(pam_handle, "pam_acct_mgmt()", last_result);
default:
case PAM_NEW_AUTHTOK_REQD:
case PAM_AUTH_ERR:
case PAM_SUCCESS:
break;
}
}pam_acct_mgmt() is supposed to check if a user account is valid. And this function IS handling the error code PAM_USER_UNKNOWN and would have thrown an Auth_Exception.
But according to my tests, pam_acct_mgmt() is actually returning error code 7 - PAM_AUTH_ERR (Authentication failure), which this code treats as "OK to proceed", which allows the autologin to proceed. I have no idea why pam_acct_mgmt() would return an authentication failure for a bad user name. Maybe a bug in the pam library?
* Possible fix
The simplest fix from within slim is to move "case PAM_AUTH_ERR:" to the first section so it throws an Auth_Exception and tells the autologin code to skip the autologin and proceed with the login GUI. I've confirmed that this change solves the autologin + bad user name crash in both Daedalus slim and "unstable" slim.
Of course, I don't know anything about PAM or what other situations could trigger a PAM_AUTH_ERR, so I don't know what side effects could occur with this change.
* Feedback: Patch-to-fix-auto_login-regression-introduced-in-1.4.patch
- This patch addresses an issue I had: when should App::Login() close the child "Untitled" window. The patch closes it as late as possible, just before Su.Login(). From my debugging, slim waits inside Su.Login() during the desktop session. So if anything went wrong earlier, the child window is still available.
- Otherwise, no suggestions, etc that I can think of.
* Feedback: Set-default-resolution-if-monitor-absent.patch
The current patch hardcodes the 1024x768 resolution when there's no monitor.
result.width = (crtc_info->width == 0 ? 1024 : crtc_info->width);
result.height = (crtc_info->height == 0 ? 768 : crtc_info->height);But I noticed that in the earlier parts of Panel::GetPrimaryViewport(), when something goes wrong, the code returns the "fallback" width and height to the caller. This "fallback" is computed from the X Window's Display's width and height. I've confirmed that this is where the 1024x768 comes from in my tests.
So a proposed solution is that when the monitor width and height are 0, use the fallback width/height. And if anything goes wrong with the fallback width/height, THEN hardcode to 1024x768.
result.width = (crtc_info->width > 0 ? crtc_info->width : fallback.width > 0 ? fallback.width : 1024);
result.height = (crtc_info->height > 0 ? crtc_info->height : fallback.height > 0 ? fallback.height : 768);Tonight, I tested the slim "suites/unstable" branch, and confirmed that the two patches did fix the problems they were supposed to fix. I also confirmed that auto-login + bad user name still crashes in the "unstable" branch, so it's still a problem.
I also have some feedback about the patches, so I'll post that in a separate comment.
And I have an explanation for the autologin + bad user name crash from examining the daedalus slim source code. I need to confirm that the explanation is still the same in "unstable" slim. Then I'll write a separate comment.
* My test notes
* Test the slim compiled from git.devuan.org
* Details
- https://git.devuan.org/devuan/slim/
- branch: suites/unstable (default branch)
* Test cases
+ slim - auto_login (yes) - untitled window?
+ Confirmed as fixed: No "untitled window" appears.
+ 2nd confirmation: In App::Login(), commenting out the new code provided by the patch "Patch-to-fix-auto_login-regression-introduced-in-1.4.patch" causes the Untitled Window to appear, confirming that this patched code is what fixed the problem.
if ( autologin )
{
//LoginPanel->ClosePanel();
}
! slim - auto_login (yes) + default_user (bad name). What will the error handling do?
! Ans: No login screen. This is the same crash reported as new in daedalus slim and excalibur slim, and still occurs on this "suites/unstable" slim.
- "ps -ef | grep slim" doesn't show slim running.
+ slim - auto_login (yes) + default_user (no name). What will the error handling do?
+ Login screen is displayed normally.
+ No regression here.
+ Monitorless auto_login (yes) - Will slim crash?
+ Confirmed as fixed: Unplug the VGA cable, power on the PC, wait for the auto login duration, plug in the VGA cable -> Xfce desktop is shown. "ps -ef | grep slim" shows that slim is running.
+ 2nd confirmation: Restoring the original code causes slim to crash again, confirming that "Set-default-resolution-if-monitor-absent.patch" has fixed this crash.
result.width = crtc_info->width;
result.height = crtc_info->height;* My setup/compile notes, in case I (or someone else) needs this
* Download commands
mkdir slimunstable
cd slimunstable
git clone https://git.devuan.org/devuan/slim/
cd slim
git status
- The default branch is suites/unstable. I assume this is the correct branch?
* Setup/compile commands
dpkg-source --before-build .
dpkg-checkbuilddeps
- This will tell you which dependencies are not found, and you'll have to install them.
debian/rules
- This creates a directory obj-x86_64-linux-gnu with a Makefile.
cd obj-x86_64-linux-gnu
make -j<number of parallel jobs>
- The executable "slim" is created in this directory.
* Copying slim to /usr/bin
- Do this just once: Make a backup of the original slim.
sudo cp -ax /usr/bin/slim /usr/bin/slim.orig_installed
- Copy the compiled slim.
sudo cp -f slim /usr/binCuriosity got to me. I rearranged some tasks and decided to take care of the "mindless" stuff tonight: install a fresh Excalibur, reproduce the known slim bugs. The goal is to do a "before and after" test, confirming that the bug WAS there, and it IS fixed.
But in doing so, I discovered ANOTHER way to crash Excalibur slim with auto login: specify a user name that doesn't exist. Additionally, I confirmed that Daedalus slim ALSO crashes in the same way. This suggests that the auto login's error handling logic is bad, and is not caused by any changes between Daedalus slim and Excalibur slim.
I don't have the focus and concentration tonight to hunt this new crash down in Daedalus slim and Excalibur slim source code to confirm that they're caused by the same bad code. So on the next block of free time, I will:
- Code review the proposed fixes to 1.4.1-1devuan4.
- Download, compile, and test the patches.
- Hunt down this new crash in Daedalus slim and Excalibur slim source code.
* My test notes
+ Test the slim currently installed
+ devuan_excalibur_6.0.0_amd64_netinstall.iso
* Software selection
- Devuan desktop environment
- Xfce
- ssh server
- standard system utilities
* Test slim, installed version
* Details
- Version: 1.4.1-1devuan1
! slim - auto_login (yes) - untitled window?
! Ans: Reproduced: Untitled window appears
! slim - auto_login (yes) + default_user (bad name). What will the error handling do?
! Ans: No login screen.
- slim appears to have crashed: "ps -ef | grep slim" doesn't show slim running.
- This is a NEW crash.
* Test on daedalus slim: 1.4.0-0devuan2
! Ans: Yes, daedalus slim ALSO crashes.
+ slim - auto_login (yes) + default_user (no name). What will the error handling do?
+ Login screen is displayed normally.
! Monitorless slim crash
! Ans: Reproduced: No login screen.
- slim appears to have crashed: "ps -ef | grep slim" doesn't show slim running.Nope. I don't mind the code review and the testing. The current problem is time. I'll have to find a block of free time without mental distractions so I can check the code, do a fresh install, test the fix, write notes, and investigate if I discover anything bizarre. But I have added this to my list of things to do.
![]()
Looking forward to installing Excalibur on some mini PCs so I can start doing useful and productive things on them. ![]()
* Edit:
I just ran a sudo apt-get update where I was testing Excalibur RC1. I got this:
N: Repository 'http://deb.devuan.org/merged excalibur InRelease' changed its 'Suite' value from 'testing' to 'stable'
N: Repository 'http://deb.devuan.org/merged excalibur-security InRelease' changed its 'Suite' value from 'testing-security' to 'stable-security'
N: Repository 'http://deb.devuan.org/merged excalibur-updates InRelease' changed its 'Suite' value from 'testing-updates' to 'stable-updates'![]()
* Analysis
Having debugged slim before for a different problem, I was able to hunt down the crash and explain the problem quickly this evening. But I don't have a solution, since I don't fully understand what this code was intending to do.
The crash occurs in panel.cpp, Panel::GetColor(), on this line:
XGetWindowAttributes(Dpy, Root, &attributes);But the problem is caused by Panel::GetPrimaryViewport(). In this function, there's new code (compared to Daedalus slim) that was added to create a child window that's the width/height of just the primary monitor. My best guess is that this was supposed to solve a problem for users with multiple monitors, where slim's login GUI might get stretched onto a 2nd monitor, or something like that.
The problem is that the code logic for finding the primary monitor's width/height never handled the case where there's NO monitor connected. In this case, the code gets back that the width/height is 0/0. The code then proceeds to create this child window using XCreateSimpleWindow(), and I think this function actually succeeds, at least, programmatically, despite being given a width/height of 0/0.
My semi-wild guess for why XGetWindowAttributes() crashes is that it's running into a divide by 0 on the width or height. I've confirmed that if either the width OR the height is 0, XGetWindowAttributes() crashes.
* Devuan's existing patch for slim
Devuan already has a patch to fix a slim auto login problem where the blank window is shown. Here's a condensed version:
/* // Disable, see Devuan#857
Root = XCreateSimpleWindow ();
XMapWindow();
XFlush();
*/The patch eliminates this child window, so slim uses the root X window, just as it did in Daedalus slim.
I tested this patch, and confirmed that this patch ALSO fixes this crash without a monitor. I think that's because the root window is created with a default resolution of the once popular 1024x768, so the rest of the X code works correctly without crashing.
So the conclusion so far is that this multimonitor feature added to slim needs more work, as it has now caused two problems - untitled window, and monitorless crash.
So the next question is, what should I do? Should I file a bug with Debian slim, since this is a separate issue?
@wert - I don't think what I'm seeing is normal. I just tested my Daedalus + Xfce + slim PC, and I set the same auto login + the same running of my multicast script on login. Then I turned off the PC, unplugged the VGA monitor cable, and turned it back on. My PC with the multicast listener DID receive the multicast, indicating that slim USED to work without needing a monitor.
I finished compiling and debugging the Excalibur slim's source code, and I'm about to write a technical explanation. For a quick explanation, there's new code in this slim that creates a temporary window that fits on one monitor. To do so, it tries to find the dimensions of the primary monitor. But the author never handled the case of having NO monitor connected. So the code thinks that the primary monitor's width/height is 0/0. Amazingly, the window IS successfully created, at least, programmatically, but the code later crashes on another X function, specifically, XGetWindowAttributes(). My guess is that XGetWindowAttributes() might be dividing by 0 somewhere in its code.
* My original problem
I wrote my own script that will send out a multicast, which can be received by my other PC. I configured Xfce on this test PC to run this script when I log in. I also configured slim to automatically log me in. That means that whenever this PC boots up and autologs in, my other PC will show a notification on the desktop that the test PC has logged in.
But when I unplugged the VGA cable from the test PC and booted it up, my other PC did NOT detect any multicast notifications. Some troubleshooting shows that when the test PC boots up without a monitor, the process "/usr/bin/slim -d" is NOT running, when it normally should be running.
I did a quick test with Daedalus + Xfce + slim with no monitor connected, and "/usr/bin/slim -d" IS running, which is the expected result. So I am suspecting that something has changed between Daedalus slim's code and Excalibur slim's code, and this change caused Excalibur slim to crash when there are no monitors detected.
Can anyone try to reproduce the problem following the steps below? Has anyone seen or heard of this problem before?
I'll spend some time compiling and debugging slim again so I can find the root cause, but if there's already a solution, that will save me some time and energy.
* Steps to reproduce
- If you have slim auto login turned on, turn it off. Edit /etc/slim.conf, comment out "auto_login". This shows that slim's auto login is NOT the cause of the problem.
- Using a stopwatch, reboot the PC. Time how long it takes for the PC to go from the BIOS to the login screen. We'll need that when we do this without a monitor.
- CTRL+ALT+F1 to go to the tty1 terminal. Log in.
- ps -ef | grep slim. This should show 3 lines:
/usr/bin/slim -d
/usr/lib/xorg/Xorg <various args>
grep slim- Turn off the PC.
- Unplug all video cables from the PC. Turning off the monitor might not be enough, because the PC can still detect the monitor.
- Turn on the PC.
- Wait for the duration measured by the stopwatch.
- Plug in the video cable.
- Press CTRL+ALT+F1 to switch to the tty1 terminal.
- If you don't see the tty1 terminal, you may have to fiddle around. Try the other terminals CTRL+ALT+F2 through F6. Try turning off/on the monitor.
- Alternatively, if you have a 2nd PC, you can telnet/ssh into your test PC to run these commands.
- ps -ef | grep slim. Instead of showing 3 lines, only TWO are shown:
/usr/lib/xorg/Xorg <various args>
grep slimMy perl script
2025.10.19: Posted the first version of the script to update the icons theme for Xfce's rDNS file names.
#!/usr/bin/perl -W
use strict ;
use warnings;
use Cwd ;
use constant false => 0;
use constant true => 1;
#In Xfce 4.16, the code switched to use rDNS (reverse DNS) icon file names. Example: The file name that Xfce expects
#for showing the desktop was changed from "user-desktop.png" to "org.xfce.panel.showdesktop.png". See:
# https://wiki.xfce.org/releng/4.16/icons_rdns_naming_for_icons
#
#In Devuan Excalibur, most of the icon themes have NOT been updated to include the rDNS files, so the theme's icons
#are not loaded.
#
#This script will take in an icon directory and add symbolic links using Xfce's new rDNS file names to the old file names
#currently in the icon theme. The symlinks are created only if the symlink doesn't exist AND if the old file name
#exists.
######## VARIABLES ########
my $gstrIconDir = ""; #The user specified directory to an icon theme. The directory must contain the file icon-theme.cache.
#A hash of Xfce's new rDNS (reverse DNS) icon file names to the old file names.
#The table came from 2 sources:
# - Xfce's official list from 4.16.
# https://wiki.xfce.org/releng/4.16/icons_rdns_naming_for_icons
# - A user's script, which contains a few more entries than the original table.
# https://gist.github.com/bluesabre/582d886a02c793285f4e3081df9b2a3c
# * Notes
# - In Xfce's list, the new "xfsm-hibernate" maps to two old files: "system-hibernate", "system-suspend-hibernate".
# In the user's script, that's mapped to only "system-suspend-hibernate".
# - I decided to support both, with "system-hibernate" as the first choice, since that more closely matches the new name.
# - In Xfce's list, the old "preferences-desktop-default-applications" is mapped to the new
# "org.xfce.settings.preferred-application". But in the user's script, it's mapped to "org.xfce.settings.default-applications".
# - I decided to map it to "preferences-desktop-default-applications", because I see it in the Xfce changelog for 4.18.
#
#For new icons that refer to multiple old file names, I used a | to separate the old file names.
my %hashXfceNewtoOldFileNames =
(
"org.xfce.about" => "help-about" ,
"org.xfce.appfinder" => "edit-find" ,
"org.xfce.catfish" => "catfish" ,
"org.xfce.Dictionary" => "xfce4-dict" ,
"org.xfce.filemanager" => "system-file-manager",
"org.xfce.genmon" => "utilities-system-monitor",
"org.xfce.gigolo" => "gtk-network" ,
"org.xfce.mailreader" => "emblem-mail" ,
"org.xfce.mousepad" => "accessories-text-editor" ,
"org.xfce.notification" => "xfce4-notifyd" ,
"org.xfce.panel" => "xfce4-panel" ,
"org.xfce.panel.actions" => "system-log-out" ,
"org.xfce.panel.applicationsmenu" => "xfce4-panel-menu" ,
"org.xfce.panel.clock" => "x-office-calendar" ,
"org.xfce.panel.directorymenu" => "folder" ,
"org.xfce.panel.launcher" => "application-x-executable" ,
"org.xfce.panel.pager" => "xfce4-workspaces" ,
"org.xfce.panel.separator" => "list-remove-symbolic" ,
"org.xfce.panel.showdesktop" => "user-desktop" ,
"org.xfce.panel.tasklist" => "preferences-system-windows",
"org.xfce.panel.windowmenu" => "preferences-system-windows",
"org.xfce.parole" => "parole" ,
"org.xfce.powermanager" => "xfce4-power-manager-settings" ,
"org.xfce.ristretto" => "ristretto" ,
"org.xfce.ScreenSaver" => "preferences-desktop-screensaver",
"org.xfce.screenshooter" => "applets-screenshooter" ,
"org.xfce.session" => "xfce4-session" ,
"org.xfce.settings.accessibility" => "preferences-desktop-accessibility" ,
"org.xfce.settings.appearance" => "preferences-desktop-theme" ,
"org.xfce.settings.color" => "xfce4-color-settings" ,
"org.xfce.settings.default-applications" => "preferences-desktop-default-applications",
"org.xfce.settings.display" => "video-display" ,
"org.xfce.settings.editor" => "preferences-system" ,
"org.xfce.settings.keyboard" => "preferences-desktop-keyboard" ,
"org.xfce.settings.manager" => "preferences-desktop" ,
"org.xfce.settings.mouse" => "preferences-desktop-peripherals" ,
"org.xfce.taskmanager" => "utilities-system-monitor",
"org.xfce.terminal-settings" => "utilities-terminal" ,
"org.xfce.terminal" => "utilities-terminal" ,
"org.xfce.terminalemulator" => "utilities-terminal" ,
"org.xfce.thunar" => "Thunar" ,
"org.xfce.volman" => "drive-removable-media",
"org.xfce.webbrowser" => "web-browser" ,
"org.xfce.workspaces" => "xfce4-workspaces" ,
"org.xfce.xfburn" => "xfburn" ,
"org.xfce.xfdashboard" => "xfdashboard" ,
"org.xfce.xfdesktop" => "preferences-desktop-wallpaper",
"org.xfce.xfmpc" => "multimedia-player" ,
"org.xfce.xfwm4-tweaks" => "wmtweaks" ,
"org.xfce.xfwm4" => "xfwm4" ,
"xfsm-hibernate" => "system-hibernate|system-suspend-hibernate",
"xfsm-lock" => "system-lock-screen",
"xfsm-logout" => "system-log-out" ,
"xfsm-reboot" => "system-reboot" ,
"xfsm-shutdown" => "system-shutdown" ,
"xfsm-suspend" => "system-suspend" ,
"xfsm-switch-user" => "system-users" ,
);
######## FUNCTIONS ########
#Perform cleanup before the script exits with the given exit code.
#
#$_[0] [in] - Optional - The exit code to exit the script with. Default = 0.
sub CleanupExit
{
my $iExitCode = @_ >= 1 ? $_[0] : 0;
#Insert extra cleanup here before the script exits.
exit($iExitCode);
}
#Args: none
#Return: 0
sub PrintHelp
{
printf("Usage: The first arg must be a directory of an icon theme. The directory must contain\n");
printf("the file \"icon-theme.cache\".\n");
return 0;
}
#Parses @ARGV for the path to the icon theme.
#
#Args: none
#
#Return: 0 on success, 1 on failure.
sub ParseArgv
{
if (scalar(@ARGV) < 1)
{
PrintHelp();
return 1;
}
my $strIconDir = $ARGV[0];
if (! -e "$strIconDir")
{
printf("!!! Error: Directory does not exist: %s\n", $strIconDir);
return 1;
}
if (! -d "$strIconDir")
{
printf("!!! Error: Specified path is not a directory: %s\n", $strIconDir);
return 1;
}
my $strIconCacheFile = "$strIconDir/icon-theme.cache";
if (! -e "$strIconCacheFile")
{
printf("!!! Error: The file \"icon-theme.cache\" was not found in the directory: %s\n", $strIconDir);
return 1;
}
if (! -f "$strIconCacheFile")
{
printf("!!! Error: The \"icon-theme.cache\" in the directory \"%s\" is not a plain file.\n", $strIconDir);
return 1;
}
$gstrIconDir = $strIconDir;
return 0;
}
#Check that the required cmds or apps are found on the path.
#
#Args: none
#
#Return: 0 on success, 1 on failure.
sub CheckRequiredCmds
{
if (system("which gtk-update-icon-cache > /dev/null") != 0)
{
printf("!!! Error: The cmd \"gtk-update-icon-cache\" was not found. This is needed to update the theme's icon cache file.\n");
return 1;
}
return 0;
}
#Helper function to read the directory entries into an array, ignoring the special directories "." and "..".
#
#Args:
# $_[0] - String of the directory name to open.
# $_[1] - A reference to an array to receive the directory entry strings.
#
#Return: 0 on success, 1 on failure.
sub ReadDirEntriesIgnoreSpDirs
{
my $strDir = $_[0];
my $refarstrDirEntries = $_[1];
my $hDIR;
@$refarstrDirEntries = ();
#Open the current directory and read all of the directory entries into an array.
if (!opendir($hDIR, $strDir))
{
printf("!!! Could not open the directory to get the subdirectories: %s\n", $strDir);
return 1;
}
my @arstrDirEntries = readdir($hDIR);
closedir($hDIR);
#Ignore the special directories "." and "..". grep keeps the elements where the block function returns true.
#$_ refers to each element in the array.
@$refarstrDirEntries = grep { $_ ne "." && $_ ne ".." } @arstrDirEntries;
return 0;
}
#Create symbolic links of the new Xfce icon names to the old file name. The symlinks are created only if the symlink
#doesn't exist AND if the old file name exists.
#
#Args: none
#
#Return: 0 on success, 1 on failure.
sub CreateNewXfceIconNames
{
my $iRet = 1, my $iNumCreated = 0;
my $hICONDIR, my $hSIZEDIR, my $hCATEGORYDIR;
my @arNewFileNameKeys = keys(%hashXfceNewtoOldFileNames);
#Supported file extensions for the icon file names.
my @arFileExt = ( ".png", ".svg" );
#Read all of the icon theme directory's entries, which should contain size subdirectories and other files.
my @arstrIconDirEntries;
if (ReadDirEntriesIgnoreSpDirs($gstrIconDir, \@arstrIconDirEntries) != 0)
{ goto CLEANUPRETURN; }
#Sort all of the arrays, so the printed output is more organized and easier for the user to see what symlinks
#were created.
@arNewFileNameKeys = sort(@arNewFileNameKeys );
@arstrIconDirEntries = sort(@arstrIconDirEntries);
foreach my $strIconDirEntry (@arstrIconDirEntries)
{
#Skip anything that's not a subdirectory.
if (! -d "$gstrIconDir/$strIconDirEntry")
{ next; }
#We're have a subdirectory name of the icon theme directory that represents the icon size.
#Example: 16x16, 22x22, scalable, etc.
my $strThisSizeDir = "$gstrIconDir/$strIconDirEntry";
#Read all of the size directory's entries, which should contain category subdirectories.
my @arstrSizeDirEntries;
if (ReadDirEntriesIgnoreSpDirs($strThisSizeDir, \@arstrSizeDirEntries))
{ goto CLEANUPRETURN; }
@arstrSizeDirEntries = sort(@arstrSizeDirEntries);
foreach my $strSizeDirEntry (@arstrSizeDirEntries)
{
#Skip anything that's not a subdirectory.
if (! -d "$strThisSizeDir/$strSizeDirEntry")
{ next; }
#We're have a subdirectory name of the size directory that represents the category.
#Example: actions, apps, places, etc.
my $strThisCategoryDir = "$strThisSizeDir/$strSizeDirEntry";
#Read all of the category directory's entries, which should contain the theme icon files.
my @arstrCategoryDirEntries;
if (ReadDirEntriesIgnoreSpDirs($strThisCategoryDir, \@arstrCategoryDirEntries))
{ goto CLEANUPRETURN; }
#Inside the category directory, we should have .png or .svg files that are the old icon files.
#They may also include new icon files if this icon theme has already been updated with the new
#Xfce rDNS file names. Also, some of these entries might be symbolic links to other files.
#Check each new file to old file mapping. If the old file is here, and the new file is NOT here,
#create a symbolic link. Check for both .png and .svg file extensions.
foreach my $strThisNewFileName (@arNewFileNameKeys)
{
#Since a new file may contain multiple old files, we separate the old file string by the | to get
#each old file name. We'll use the first matching old file.
#Example: "xfsm-hibernate" => "system-hibernate|system-suspend-hibernate"
my @arstrOldFileNames = split(/\|/, $hashXfceNewtoOldFileNames{$strThisNewFileName});
#Check each of the supported file extensions. Example: .png, .svg.
foreach my $strThisFileExt (@arFileExt)
{
foreach my $strThisOldFileName (@arstrOldFileNames)
{
my $strThisOldFileNameExt = $strThisOldFileName . $strThisFileExt;
my $strThisNewFileNameExt = $strThisNewFileName . $strThisFileExt;
if (-e "$strThisCategoryDir/$strThisNewFileNameExt")
{ next; } #This new icon file has already been created.
#This new icon file hasn't been created. Check if the old icon file exists in this category directory.
#$_ refers to each element in the array.
my @grepRet = grep { $_ eq $strThisOldFileNameExt } @arstrCategoryDirEntries;
if (scalar(@grepRet) == 0)
{ next; } #The old icon file wasn't found in this directory. Can't make a symlink.
#Construct the command to create the new file symbolic link to the old file. Reminder
#that the new symlink is supposed to be in the same directory as the old file. But we're not
#inside this category directory. So the symlink command will contain just the old file name
#as the "target", and the "link name" will be a path to where the symlink will be created.
#Example:
# ln -sv "user-desktop.png" "Tango/32x32/places/org.xfce.panel.showdesktop.png"
#
# -s : create symbolic link
# -v : print name of each linked file
my $strCmd = sprintf("ln -sv \"%s\" \"%s/%s\"", $strThisOldFileNameExt, $strThisCategoryDir, $strThisNewFileNameExt);
if (system($strCmd) != 0)
{ goto CLEANUPRETURN; }
#We've created a new icon file name symlink to one of the old files. Skip any other old file names.
$iNumCreated++;
last;
}
}
#we're done with this new icon file name.
}
#We're done with this category subdirectory.
}
#We're done with this size subdirectory.
}
if ($iNumCreated > 0)
{
printf("\n");
printf("* Updating the theme's \"icon-theme.cache\" so it knows about the new files.\n");
my $strCmd = sprintf("gtk-update-icon-cache \"%s\"", $gstrIconDir);
if (system($strCmd) != 0)
{ goto CLEANUPRETURN; }
}
else
{
printf("* No new files were created. Skipping updating the theme's \"icon-theme.cache\".\n");
}
#We've successfully updated the icon theme directory.
$iRet = 0;
CLEANUPRETURN:
return $iRet;
}
######## BEGIN SCRIPT ########
ParseArgv () == 0 || CleanupExit(1);
CheckRequiredCmds () == 0 || CleanupExit(1);
CreateNewXfceIconNames() == 0 || CleanupExit(1);
CleanupExit 0;
######## END SCRIPT ########* Intro
After a fresh Excalibur + Xfce install, I tried changing the icon theme to Tango (Applications -> Settings -> Appearance). I noticed that the application icons along the bottom panel didn't change. In fact the only theme that showed any changes was the Deepsea theme.
From my research, in Xfce 4.16, they changed the code to look for rDNS (reverse DNS) icon file names. Example, for the "Show Desktop" icon, Xfce previously looked for "user-desktop.png". In 4.16, the code now looks for "org.xfce.panel.showdesktop.png".
Some solutions online says that you can update the icon theme by creating a symbolic link with the new rDNS file name and point it to the original file. But an icon theme has icons for multiple sizes (16x16, 24x24, etc). So it would be very tedious to manually add all of these symlinks for all of these sizes.
I wrote a Perl script that contains these file name mappings, and it will create a symlink if the new file name doesn't exist and if the old file name exists. I tested it on several of the Xfce icon themes, and it seems to work correctly, so I'm sharing the script with instructions.
By the way, the reason why the Deepsea theme changed was that some people from Devuan went to the Xfce forums and posted some questions about the icons. So they added a few symlinks with the rDNS file names to the Deepsea theme, which is why that theme showed a difference.
* Old to new icon file name mappings
Excalibur's Xfce is version 4.20. But I couldn't find any definitive list of icon file name mappings. The best I could do was to start with the file name mappings published for 4.16:
https://wiki.xfce.org/releng/4.16/icons … _for_icons
and include extra entries found in a user's script:
https://gist.github.com/bluesabre/582d8 … 81df9b2a3c
* Instructions
This example will update the Tango icon theme.
- Copy the code in the next comment into a perl script file. Example: /tmp/fix_xfce_icon_names.pl
- Make the file executable.
chmod +x /tmp/fix_xfce_icon_names.pl- Create an icons directory in your home directory if it doesn't exist, then go into it.
mkdir -p ~/.local/share/icons
cd ~/.local/share/icons- Inside your local icons directory, copy the Tango icon theme to this directory. This example will use a different directory name, so you can tell that this is the modified theme. The "-a" is the "archive" mode, which tries to preserve all of the file properties, so you can tell which files were the original files by the modified date if needed.
cp -a /usr/share/icons/Tango Tango2- Staying in your local icons directory, run the icon update script on Tango2.
/tmp/fix_xfce_icon_names.pl Tango2- Recommended: Update the display name for Tango2, so you can tell the difference from the original Tango theme in Xfce's Appearance app.
mousepad Tango2/index.themeChange the "Name=" to "Tango2" and the "Comment=" to include Tango2.
- Launch a new instance of the Appearance app.
Applications -> Settings -> Appearance -> Icons tab
You can now switch between Tango and Tango2 and see the updated icon names taking effect.
- If anything goes wrong, you can delete your local Tango2 and start again.
- Also, I recommend saving the perl script to a more permanent location so you can run it again if you want to use a different icon theme.
@ralph.ronnquist - Thanks for the tips. I have a feeling I'm be referring to your comment soon as I continue testing the MATE and Xfce desktops.
@golinux - The most I can tell you is that during my Excalibur + MATE desktop testing, I did a quick test of all of the clearlooks-phenix themes (cinnabar, darkpurpy, deepsea, lightpurpy, sapphire), and the lightpurpy was the only one that didn't load. That's when I investigated that theme to find the root cause.
@fsmithred - I just confirmed that the light purpy theme installed manually (sudo apt-get install ./clearlooks-phenix-lightpurpy-theme_7.0.1-6_all.deb) now loads correctly in the MATE desktop's Appearance app, instead of showing a question mark. This confirms the fix for this theme's package. This ends the sidetrack to the light purpy theme problem. Thanks for fixing it.
So back on topic, the current status is that Excalibur has a proposed fix to slim that restores the previous auto-login behavior (without the Untitled window), but potentially breaks an upcoming slim feature involving multiple monitors. Someone has also filed the same bug in Debian slim, so they might have a better fix.
@fsmithred - Off topic: Are you still the maintainer of the package "clearlooks-phenix-lightpurpy-theme"? I filed a bug on Sep 9, and the last email I got was "Your message to Devuan-bugs awaits moderator approval".
Excalibur + MATE Desktop: clearlooks-phenix-lightpurpy-theme doesn't work
The fix should be pretty easy: fix the theme's installed directory's capitalizaton. I'd like to verify the fix and have 1 fewer bug before Excalibur's release.
@fsmithred - I retested using the live desktop and downloading the source code. This time, I added the "excalibur-proposed-updates" deb-src line. When I download the source code using "apt source --compile slim", I can now see that at the bottom of Panel.cpp, the code that creates the child window using XCreateSimpleWindow() IS commented out, which explains why the live desktop's slim doesn't show the "Untitled window", but the login screen's background image tiles onto the 2nd monitor - the login window is using the Root window owned by the X server, which stretches over both monitors.
================
I looked through commit history for the branch "suites/excalibur-proposed-updates":
https://git.devuan.org/devuan/slim/src/ … ed-updates
and I found the commit named "New upstream version 1.4.1" that added the code to create this child window:
https://git.devuan.org/devuan/slim/comm … ec660f25c4
I was trying to find out WHY this child window was created. And the only clue I have is in the new lines added to the ChangeLog. This one appears relevant to the child window:
Adjusted how/when the pseudo-root window is created and removed, in
preparation for handling multiple monitors in SLiMI'm not sure what feature slim will implement that requires multiple monitors. One guess is for a multi-monitor setup, slim wants to allow the user to specify WHICH monitor to show the login GUI. That would mean that slim will need to create this child window for the user-specified monitor. So I can see why commenting this out would be the "wrong" fix in the long term, because the child window is needed for a multi-monitor feature.
================
Something I learned the hard way. When you first showed me the URL to the git repository for the excalibur-proposed-updates:
https://git.devuan.org/devuan/slim/src/ … ed-updates
I downloaded panel.cpp, examined the end of the file, and saw that the child window code was NOT commented out. Furthermore, the file was last modified 1 year ago. So I couldn't understand how this fix for the "Untitled window" was recently put into "excalibur-proposed-updates" and would be available soon.
After looking around the repository. I now see that this fix was never checked as a change to panel.cpp. Instead, it was checked in as a patch file in the subdirectory debian/patches.
https://git.devuan.org/devuan/slim/src/ … an/patches
When I used "apt source --compile slim", the command automatically applied the patches, which explains why I DO see that the child window code was commented out.
So the hard lesson learned is that if you go to these repositories in a web browser and download a source file to examine it, you might not be reading code that matches the compiled binary file, because the compiled binary file may include patches in debian/patches that changes the source code. Nasty gotcha if you're new to this.
That's all for tonight. ![]()
@fsmithred - I confirmed that the live desktop rc2 is using slim. And I do not see the "Untitled window" when the live desktop auto logs in. I also did a 2-monitor test, and slim's background DOES tile onto the 2nd monitor.
The problem is that both of these behaviors are not possible with the source code downloaded from "apt source --compile slim". I did that from the live desktop (see my test notes), and confirmed that the source code IS creating the child window "Untitled window" and the background should NOT tile onto the 2nd monitor.
The only conclusion I can think of is that you're building slim for the live desktop from a different source code than what's available from "apt source". Perhaps your versiom of slim code INCLUDES the code change that comments out creating the child window?
Other than that, there were no surprises in my rc2 live desktop tests.
* Test Notes
- Confirm that slim is the display manager.
+ Ans: Yes. "ps -ef | grep slim" shows "/usr/bin/slim -d".
- Screen resolution OK?
+ Ans: Yes. xrandr shows 1920x1080 on FX-8120's monitor, 1600x900 on A6-3620's monitor.
- I was testing both PCs at the same time. Each PC has its own monitor. These resolutions are the correct max resolution for the connected monitor.
- Check that slim.conf has auto login enabled.
+ Ans: Yes, "cat /etc/slim.conf" shows:
default_user devuan
auto_login yes
- Check if slim + auto login showed the "Untitled window".
+ Ans: slim + auto login did NOT show an "Untitled window".
? How is this possible? Does this build contain the code change that disabled slim from creating the child window that causes the "Untitled window"? Or is this using an older version of slim?
- Version of slim: "apt show slim" shows version is "1.4.1-devuan1+excalibur1".
- Also, "slim -v" shows 1.4.1.
- This seems like the current version. Daedalus slim was 1.4.0.
- I downloaded the source code using "apt source --compile slim". This includes enabling deb-src, installing dpkg-dev. I didn't install all of the dependencies required to compile, just enough to get the source code patched and the compiling started.
- Taking a look at panel.cpp, at the bottom, slim's code IS creating the child window. Why don't I see it in the live desktop auto login??? Is the source code from apt source NOT correct for the slim binary in the live desktop???
- I can't compile and test slim like I did yesterday, because it requires a reboot to run the compiled slim binary, which will wipe out the live desktop environment. This is as far as I can go.
- Logging out, then logging back in as devuan/devuan, any problems?
+ Ans: No problems seen.
- Quick check: Confirm that RAID is NOT installed on the live desktop.
+ Ans: Confirmed. "cat /proc/mdstat" shows "No such file or directory".
- Quick check: There's an mdadm.deb in the root / directory.
+ Ans: Confirmed. mdadm_4.4-11devuan3_amd64.deb is there.
- Dual monitor test: Reboot to a fresh live desktop, then log out to observe the slim login GUI and background.
? Ans: The background tiles to the 2nd monitor, even though the source code says the child window IS being created with the dimensions of the 1st monitor, which should keep the background ONLY on the 1st monitor. There's definitely a source code to binary mismatch (or some voodoo magic) going on with the live desktop slim.
- Memtest: still runs?
+ Ans: Both menu options worked in UEFI and legacy boot.@fsmithred: I never figured out how to download from git, and I don't think I'll have time to sidetrack and figure that out (waaay too many other hobby-time projects in progress). So I can't compile and test the "excalibur-proposed-updates" branch.
But I CAN download the two main files related to this problem - "app.cpp", "panel.cpp" - and compare them to the Excalibur slim that I debugged today. I don't see any changes in "excalibur-proposed-updates" that would fix this "Untitled window" problem. None of the code changes have anything to do with this child window that slim is creating.
I did some tests between Dadealus's slim and Excalibur's slim. I don't have an explanation for why the code was changed, but I have a guess. I also don't have a good proposal for a solution, because I don't understand enough about the login error handling and XWindows to figure out where to move the code. Not in one afternoon, anyway.
* Daedalus slim
When Daedalus slim shows the login screen, if there are 2 monitors, the login screen is shown on one monitor, and the other monitor shows the background. In the case of Devuan, the background is a small solid blue 50x31 image, which slim tiles horizontally and vertically. So slim shows a solid blue background, which looks OK on the 2nd monitor.
But if you have a unique background image, that unique image gets tiled over to the 2nd monitor. Now the user sees two monitors with this unique background, but only one of them contains the login screen. So this is my guess as to the original reason why the code was changed - to not show anything on the 2nd monitor, which does not contain any login GUI, to avoid confusing the user.
When slim starts, it requests for a Display, a Screen, and a Root window. I don't understand these XWindows concepts, but my debugging shows that the width and height is the sum of both monitors side by side, such as 3840x1080.
* Excalibur slim
In Excalibur slim, the implemented solution was to create a child window that's the width/height of just the primary monitor. All of the login window's GUI/background/etc will be placed inside this child window. As a result, nothing is shown on the 2nd monitor.
When you log in manually, Excalibur slim destroys the child window that it created, so you don't see this child window.
But when you autologin, the code jumps straight to the user/password login logic, and never destroys this child window, resulting in this "Untitled window" that's the size of the primary monitor. That's because the code never NEEDED to clean up any child windows before. The previous Root window was owned by the X server.
So it sounds easy to say "just destroy the child window before doing the auto login", but I don't know what happens if the auto login fails and slim has to show the login GUI. Will the code recreate a new child window for the login GUI? If yes, someone will have to move the code logic so this child window gets recreated when it's needed. This means refactoring the code and retesting the different code paths, including error handling code paths.
The reason why commenting out the code block seems to work is that both the child window and the Root window refer to the same Root window. So the behavior ends up being the same as Daedalus slim - there's no untitled window, but the background tiles to the 2nd monitor. And the slim code is smart enough to recognize that the child window refers to the same Root window, so it does NOT try to destroy the Root window that it didn't create.
That's all the time I have for this problem. It'll be up to the Debian maintainers who should know this code better than I can - at least in 1 afternoon's debugging - to figure out a good solution.
Yes, I understand. That's why I'm currently trying to figure out how to download the slim package so I can read the code and get an idea of what that area of code is doing. It's not something I wanted to do today, but I want a reliable fix.
One thing that makes me uneasy about the fix, the guy wrote:
"Maybe someone who actually knows what they are doing can fix this?"
That always makes me nervous about whether the code change is really a fix, or whether it breaks something else. We'll see. ![]()