This forum has been archived. All content is frozen. Please use KDE Discuss instead.

The correct way to change wallpaper from script

Tags: None
(comma "," separated)
User avatar
blindvic
Registered Member
Posts
157
Karma
0
OS
There are many forum threads on this topic - how to change KDE4 wallpaper from a script.
Some of them are outdated, other say plasma doesn't support yet this via an interface...

http://ubuntuforums.org/showpost.php?p= ... stcount=14

So, my question is:
What is the latest and correct way to change the wallpaper given its path?

Is it still editing plasma-desktop-appletsrc file?
Is there and dbus method for this?
Other?
User avatar
bcooksley
Administrator
Posts
19765
Karma
87
OS
At this time there is still no possible method to change the wallpaper from a remote script. The fully Plasma integrated and runtime way to change it is by using a Plasma script, which is written in Javascript.

Unfortunately, for security reasons, external applications cannot yet run scripts. However, they are able to cause the script runner to come on screen, and be preloaded with a script from a file.


KDE Sysadmin
[img]content/bcooksley_sig.png[/img]
User avatar
einar
Administrator
Posts
3402
Karma
7
OS
If you have 4.6 the best way is to make a wallpaper of a fixed name (e.g. "wallpaper.png") then if you want to change a wallpaper, rename the one picked by your script to that name. Plasma will detect the file change and display the new wallpaper.

The only other way is a hack involving QMetaObject's invokeMethod() which is a terrible hack and IMO not future-proof.


"Violence is the last refuge of the incompetent."
Image
Plasma FAQ maintainer - Plasma programming with Python
richardpnz
Registered Member
Posts
1
Karma
0
OS
Thanks to the help above I was able to change this.
My screen is 1440x900.
I downloaded one wallpaper 1920x1080- a mountain
And one wallpaper 1440x900- a beach.
I renamed the "lovelock.png" file in the folder
/usr/share/kde4/apps/ksplash/Themes/Lovelock/1920x1200/lovelock.png
as "lovelock2.png"

Using GIMP I saved the 1920x1080 mountain wallpaper as "lovelock.png" here:
/usr/share/kde4/apps/ksplash/Themes/Lovelock/1920x1200/lovelock.png
I left its size as 1920x1080.
And I saved the 1440x900 beach wallpaper here
/usr/share/kde4/apps/ksplash/Themes/Lovelock/1440x900/lovelock.png
I left it as 1440x900. I had to create the new folder "1440x900" as there was not one.

After reboot the beach wallpaper appeared on screen. It was a bit blurry as its resolution did not match my screen.
After 10 seconds it was replaced by the 1440x900 beach scene, sharply displayed in the correct resolution.

So I am surprised that such a popular feature is so hard to change. But at least it can be done.

Thanks
User avatar
blindvic
Registered Member
Posts
157
Karma
0
OS
I just did a script to change wallpaper and it works:
Code: Select all
#!/usr/bin/env python3
import sys
import os
import subprocess

import dbus
from PyQt4 import QtGui
from PyKDE4.kdecore import KConfig


activity_manager = dbus.SessionBus().get_object('org.kde.kactivitymanagerd', '/ActivityManager')
current_activity_id = dbus.Interface(activity_manager, 'org.kde.ActivityManager').CurrentActivity()
print('Current activity ID:', current_activity_id)

kwin = dbus.SessionBus().get_object('org.kde.kwin', '/KWin')
print('Current desktop:', dbus.Interface(kwin, 'org.kde.KWin').currentDesktop())

print('Primary screen:', QtGui.QApplication(sys.argv).desktop().primaryScreen())

konf_path = os.path.expanduser('~/.kde/share/config/plasma-desktop-appletsrc')
# http://api.kde.org/pykde-4.7-api/kdecore/KConfig.html
konf = KConfig(konf_path, KConfig.SimpleConfig)
containments = konf.group('Containments')
for group_name in containments.groupList():
    group = containments.group(group_name)
    # http://api.kde.org/pykde-4.7-api/kdecore/KConfigGroup.html
    if group.readEntry('activityId') == current_activity_id:
        print('Containment ID of the current activity:', group_name)
        wallpaper_image_group = group.group('Wallpaper').group('image')
        wallpaper_image_group.writeEntry('wallpaper', '/home/vic/.kde/share/wallpapers/morning 3 machu picchu peru-X3.jpg')


# dbus call does not cause wallpaper change, i guess applet config is not re-read
# plasma = dbus.SessionBus().get_object('org.kde.plasma-desktop', '/MainApplication')
# dbus.Interface(plasma, 'org.kde.KApplication').reparseConfiguration()

print('Restarting plasma...')
with open(os.devnull, "w") as fnull:
    subprocess.call('kquitapp plasma-desktop && sleep 2s', shell=True, stdout=fnull, stderr=fnull)
    konf.sync()  # save the configuration
    subprocess.call('plasma-desktop &', shell=True, stdout=fnull, stderr=fnull)

I gets current activity id and finds all containments that match it, replacing wallpaper setting entry in them, stops plasma, saves the config and starts plasma.
I my plasma-desktop-appletsrc file there are two containments for the current activity id:
Code: Select all
[Containments][12]
activity=Desktop
activityId=5f8e5c63-c0a0-4e5e-bd21-6f805bc791d7
desktop=-1
formfactor=0
geometry=0,0,1366,768
immutability=1
lastDesktop=-1
lastScreen=0
location=0
plugin=folderview
screen=0
url=desktop:/
wallpaperplugin=image
wallpaperpluginmode=SingleImage
zvalue=0

[Containments][18]
ActionPluginsSource=Global
activity=Desktop
activityId=5f8e5c63-c0a0-4e5e-bd21-6f805bc791d7
desktop=-1
formfactor=0
geometry=0,924,1920,1080
immutability=1
lastDesktop=-1
lastScreen=1
location=0
plugin=desktop
screen=1
wallpaperplugin=image
wallpaperpluginmode=SingleImage
zvalue=0

and the output of the script is:
Code: Select all
Current activity ID: 5f8e5c63-c0a0-4e5e-bd21-6f805bc791d7
Current desktop: 1
Primary screen: 1699574904
Containment ID of the current activity: 12
Containment ID of the current activity: 18
Restarting plasma...

I need your comments on the idea and the code.
Also, i guess, it would be nice to change the wallpaper only for the current screen? Should change wallpaper settings only for the containment with `screen` setting that matches the result of dbus.Interface(kwin, 'org.kde.KWin').currentDesktop() call? But in my case it returns 1 while in the settings it's 0 for my current desktop. How to find the current `screen` number that is the same as the one in plasma settings?


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]