Support wallpaper switching and fix up select-wallpaper
This commit is contained in:
parent
dd823cd835
commit
2adc4fefec
@ -123,44 +123,13 @@ static void redraw(void) {
|
|||||||
|
|
||||||
static int find_wallpaper_pid(void) {
|
static int find_wallpaper_pid(void) {
|
||||||
|
|
||||||
DIR * dirp = opendir("/proc");
|
FILE * f = fopen("/tmp/.wallpaper.pid","r");
|
||||||
int out_pid = 0;
|
int out_pid = 0;
|
||||||
|
if (f) {
|
||||||
/* Read the entries in the directory */
|
fscanf(f, "%d",&out_pid);
|
||||||
list_t * ents_list = list_create();
|
|
||||||
|
|
||||||
struct dirent * ent = readdir(dirp);
|
|
||||||
while (ent != NULL) {
|
|
||||||
if (ent->d_name[0] >= '0' && ent->d_name[0] <= '9') {
|
|
||||||
char tmp[256], buf[4096], name[128];
|
|
||||||
FILE * f;
|
|
||||||
int read = 1;
|
|
||||||
char line[LINE_LEN];
|
|
||||||
|
|
||||||
snprintf(tmp, 256, "/proc/%s/status", ent->d_name);
|
|
||||||
f = fopen(tmp, "r");
|
|
||||||
|
|
||||||
while (fgets(line, LINE_LEN, f) != NULL) {
|
|
||||||
if (strstr(line, "Name:") == line) {
|
|
||||||
sscanf(line, "%s %s", &buf, &name);
|
|
||||||
if (!strcmp(name, "wallpaper")) {
|
|
||||||
out_pid = atoi(ent->d_name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
if (out_pid) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ent = readdir(dirp);
|
|
||||||
}
|
}
|
||||||
closedir(dirp);
|
|
||||||
|
|
||||||
return out_pid;
|
return out_pid;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite_t * load_wallpaper(char * file) {
|
sprite_t * load_wallpaper(char * file) {
|
||||||
@ -304,7 +273,7 @@ static void button_prev(struct button * this) {
|
|||||||
} else {
|
} else {
|
||||||
selected_wallpaper = selected_wallpaper->prev;
|
selected_wallpaper = selected_wallpaper->prev;
|
||||||
if (!selected_wallpaper) {
|
if (!selected_wallpaper) {
|
||||||
selected_wallpaper = wallpapers->head;
|
selected_wallpaper = wallpapers->tail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ on providing a more easily extended widget system. Each element of the panel is
|
|||||||
a widget object which can independently draw and receive mouse events.
|
a widget object which can independently draw and receive mouse events.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import configparser
|
||||||
import math
|
import math
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import os
|
|
||||||
|
|
||||||
import cairo
|
import cairo
|
||||||
|
|
||||||
@ -148,7 +150,7 @@ class LogOutWidget(BaseWidget):
|
|||||||
self.hilighted = False
|
self.hilighted = False
|
||||||
|
|
||||||
def mouse_action(self, msg):
|
def mouse_action(self, msg):
|
||||||
if msg.command == 0:
|
if msg.command == yutani.MouseEvent.CLICK:
|
||||||
yctx.session_end()
|
yctx.session_end()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -211,7 +213,7 @@ class VolumeWidget(BaseWidget):
|
|||||||
self.set_volume()
|
self.set_volume()
|
||||||
|
|
||||||
def mouse_action(self, msg):
|
def mouse_action(self, msg):
|
||||||
if msg.command == 0:
|
if msg.command == yutani.MouseEvent.CLICK:
|
||||||
if self.muted:
|
if self.muted:
|
||||||
self.muted = False
|
self.muted = False
|
||||||
self.volume = self.previous_volume
|
self.volume = self.previous_volume
|
||||||
@ -223,10 +225,10 @@ class VolumeWidget(BaseWidget):
|
|||||||
self.set_volume()
|
self.set_volume()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
if msg.buttons & yutani.MouseButton.SCROLL_UP: # Scroll up (TODO: Put these somewhere useful)
|
if msg.buttons & yutani.MouseButton.SCROLL_UP:
|
||||||
self.volume_up()
|
self.volume_up()
|
||||||
return True
|
return True
|
||||||
elif msg.buttons & yutani.MouseButton.SCROLL_DOWN: # Scroll down (TODO: Put these somwhere useful)
|
elif msg.buttons & yutani.MouseButton.SCROLL_DOWN:
|
||||||
self.volume_down()
|
self.volume_down()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -295,7 +297,7 @@ class WindowListWidget(BaseWidget):
|
|||||||
previously_hovered = self.hovered
|
previously_hovered = self.hovered
|
||||||
if hovered_index < len(windows):
|
if hovered_index < len(windows):
|
||||||
self.hovered = windows[hovered_index].wid
|
self.hovered = windows[hovered_index].wid
|
||||||
if msg.command == 0:
|
if msg.command == yutani.MouseEvent.CLICK:
|
||||||
yctx.focus_window(self.hovered)
|
yctx.focus_window(self.hovered)
|
||||||
elif msg.buttons & yutani.MouseButton.BUTTON_RIGHT:
|
elif msg.buttons & yutani.MouseButton.BUTTON_RIGHT:
|
||||||
if not menus:
|
if not menus:
|
||||||
@ -339,7 +341,6 @@ class MenuEntryAction(object):
|
|||||||
self.hilight = False
|
self.hilight = False
|
||||||
self.window = None
|
self.window = None
|
||||||
self.gradient = cairo.LinearGradient(0,0,0,self.height-2)
|
self.gradient = cairo.LinearGradient(0,0,0,self.height-2)
|
||||||
# TODO actual gradient for this
|
|
||||||
self.gradient.add_color_stop_rgba(0.0,*self.hilight_gradient_top,1.0)
|
self.gradient.add_color_stop_rgba(0.0,*self.hilight_gradient_top,1.0)
|
||||||
self.gradient.add_color_stop_rgba(1.0,*self.hilight_gradient_bottom,1.0)
|
self.gradient.add_color_stop_rgba(1.0,*self.hilight_gradient_bottom,1.0)
|
||||||
|
|
||||||
@ -386,7 +387,7 @@ class MenuEntryAction(object):
|
|||||||
self.tr.draw(window)
|
self.tr.draw(window)
|
||||||
|
|
||||||
def mouse_action(self, msg):
|
def mouse_action(self, msg):
|
||||||
if msg.command == 0: # click (TODO: SERIOUSLY, add this into the yutani library)
|
if msg.command == yutani.MouseEvent.CLICK:
|
||||||
if self.action:
|
if self.action:
|
||||||
self.action(self.data) # Probably like launch_app("terminal")
|
self.action(self.data) # Probably like launch_app("terminal")
|
||||||
self.focus_leave()
|
self.focus_leave()
|
||||||
@ -588,7 +589,10 @@ class ApplicationsMenuWidget(BaseWidget):
|
|||||||
MenuEntryAction("RPG Demo","applications-simulation",menu_callback,"game"),
|
MenuEntryAction("RPG Demo","applications-simulation",menu_callback,"game"),
|
||||||
]),
|
]),
|
||||||
MenuEntrySubmenu("Graphics",[
|
MenuEntrySubmenu("Graphics",[
|
||||||
MenuEntryAction("Draw!","applications-painting",menu_callback,"draw")
|
MenuEntryAction("Draw!","applications-painting",menu_callback,"draw"),
|
||||||
|
]),
|
||||||
|
MenuEntrySubmenu("Settings",[
|
||||||
|
MenuEntryAction("Select Wallpaper","select-wallpaper",menu_callback,"select-wallpaper"),
|
||||||
]),
|
]),
|
||||||
MenuEntryDivider(),
|
MenuEntryDivider(),
|
||||||
MenuEntryAction("Help","help",menu_callback,"help-browser"),
|
MenuEntryAction("Help","help",menu_callback,"help-browser"),
|
||||||
@ -607,7 +611,7 @@ class ApplicationsMenuWidget(BaseWidget):
|
|||||||
self.font.font_color = self.color
|
self.font.font_color = self.color
|
||||||
|
|
||||||
def mouse_action(self,msg):
|
def mouse_action(self,msg):
|
||||||
if msg.command == 0:
|
if msg.command == yutani.MouseEvent.CLICK:
|
||||||
menu = MenuWindow(self.menu_entries,(0,PANEL_HEIGHT))
|
menu = MenuWindow(self.menu_entries,(0,PANEL_HEIGHT))
|
||||||
|
|
||||||
|
|
||||||
@ -776,12 +780,14 @@ class WallpaperIcon(object):
|
|||||||
self.hilighted = False
|
self.hilighted = False
|
||||||
|
|
||||||
def mouse_action(self, msg):
|
def mouse_action(self, msg):
|
||||||
if msg.command == 0:
|
if msg.command == yutani.MouseEvent.CLICK:
|
||||||
self.action(self)
|
self.action(self)
|
||||||
|
|
||||||
class WallpaperWindow(yutani.Window):
|
class WallpaperWindow(yutani.Window):
|
||||||
"""Manages the desktop wallpaper window."""
|
"""Manages the desktop wallpaper window."""
|
||||||
|
|
||||||
|
fallback = '/usr/share/wallpapers/default'
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
w = yutani.yutani_ctx._ptr.contents.display_width
|
w = yutani.yutani_ctx._ptr.contents.display_width
|
||||||
h = yutani.yutani_ctx._ptr.contents.display_height
|
h = yutani.yutani_ctx._ptr.contents.display_height
|
||||||
@ -791,10 +797,16 @@ class WallpaperWindow(yutani.Window):
|
|||||||
self.set_stack(yutani.WindowStackOrder.ZORDER_BOTTOM)
|
self.set_stack(yutani.WindowStackOrder.ZORDER_BOTTOM)
|
||||||
|
|
||||||
# TODO get the user's selected wallpaper
|
# TODO get the user's selected wallpaper
|
||||||
self.background = self.load_wallpaper('/usr/share/wallpapers/default')
|
self.background = self.load_wallpaper()
|
||||||
self.icons = self.load_icons()
|
self.icons = self.load_icons()
|
||||||
self.focused_icon = None
|
self.focused_icon = None
|
||||||
self.animations = {}
|
self.animations = {}
|
||||||
|
self.x = 0 # For clipping
|
||||||
|
self.y = 0
|
||||||
|
|
||||||
|
def animate_new(self):
|
||||||
|
self.new_background = self.load_wallpaper()
|
||||||
|
self.animations[self] = time.time()
|
||||||
|
|
||||||
def add_animation(self, icon):
|
def add_animation(self, icon):
|
||||||
self.animations[icon] = time.time()
|
self.animations[icon] = time.time()
|
||||||
@ -804,6 +816,8 @@ class WallpaperWindow(yutani.Window):
|
|||||||
self.draw(self.animations.keys())
|
self.draw(self.animations.keys())
|
||||||
ditch = []
|
ditch = []
|
||||||
for icon in self.animations:
|
for icon in self.animations:
|
||||||
|
if icon == self:
|
||||||
|
continue
|
||||||
if tick - self.animations[icon] > 0.5:
|
if tick - self.animations[icon] > 0.5:
|
||||||
ditch.append(icon)
|
ditch.append(icon)
|
||||||
for icon in ditch:
|
for icon in ditch:
|
||||||
@ -831,7 +845,18 @@ class WallpaperWindow(yutani.Window):
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def load_wallpaper(self, path):
|
def load_wallpaper(self, path=None):
|
||||||
|
if not path:
|
||||||
|
home = os.environ['HOME']
|
||||||
|
conf = f'{home}/.desktop.conf'
|
||||||
|
if not os.path.exists(conf):
|
||||||
|
path = self.fallback
|
||||||
|
else:
|
||||||
|
with open(conf,'r') as f:
|
||||||
|
conf_str = '[desktop]\n' + f.read()
|
||||||
|
c = configparser.ConfigParser()
|
||||||
|
c.read_string(conf_str)
|
||||||
|
path = c['desktop'].get('wallpaper',self.fallback)
|
||||||
return cairo.ImageSurface.create_from_png(path)
|
return cairo.ImageSurface.create_from_png(path)
|
||||||
|
|
||||||
def finish_resize(self, msg):
|
def finish_resize(self, msg):
|
||||||
@ -874,7 +899,35 @@ class WallpaperWindow(yutani.Window):
|
|||||||
ctx.paint()
|
ctx.paint()
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
|
|
||||||
|
|
||||||
ctx.set_operator(cairo.OPERATOR_OVER)
|
ctx.set_operator(cairo.OPERATOR_OVER)
|
||||||
|
clear_animation = False
|
||||||
|
|
||||||
|
if self in self.animations:
|
||||||
|
ctx.save()
|
||||||
|
x = self.width / self.new_background.get_width()
|
||||||
|
y = self.height / self.new_background.get_height()
|
||||||
|
|
||||||
|
nh = int(x * self.new_background.get_height())
|
||||||
|
nw = int(y * self.new_background.get_width())
|
||||||
|
|
||||||
|
if (nw > self.width):
|
||||||
|
ctx.translate((self.width - nw) / 2, 0)
|
||||||
|
ctx.scale(y,y)
|
||||||
|
else:
|
||||||
|
ctx.translate(0,(self.height - nh) / 2)
|
||||||
|
ctx.scale(x,x)
|
||||||
|
|
||||||
|
ctx.set_source_surface(self.new_background,0,0)
|
||||||
|
diff = time.time()-self.animations[self]
|
||||||
|
if diff >= 1.0:
|
||||||
|
self.background = self.new_background
|
||||||
|
clear_animation = True
|
||||||
|
ctx.paint()
|
||||||
|
else:
|
||||||
|
ctx.paint_with_alpha(diff/1.0)
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
|
||||||
offset_x = 20
|
offset_x = 20
|
||||||
offset_y = 50
|
offset_y = 50
|
||||||
@ -886,10 +939,12 @@ class WallpaperWindow(yutani.Window):
|
|||||||
last_width = 0
|
last_width = 0
|
||||||
if icon.width > last_width:
|
if icon.width > last_width:
|
||||||
last_width = icon.width
|
last_width = icon.width
|
||||||
if not clips or icon in clips or icon in self.animations:
|
if not clips or icon in clips or icon in self.animations or self in self.animations:
|
||||||
icon.draw(self,(offset_x,offset_y),ctx,time.time()-self.animations[icon] if icon in self.animations else False)
|
icon.draw(self,(offset_x,offset_y),ctx,time.time()-self.animations[icon] if icon in self.animations else False)
|
||||||
offset_y += icon.height
|
offset_y += icon.height
|
||||||
|
|
||||||
|
if clear_animation:
|
||||||
|
del self.animations[self]
|
||||||
|
|
||||||
self.flip()
|
self.flip()
|
||||||
|
|
||||||
@ -1015,6 +1070,10 @@ def finish_alt_tab(msg):
|
|||||||
|
|
||||||
alttab.close()
|
alttab.close()
|
||||||
|
|
||||||
|
def reload_wallpaper(signum, frame):
|
||||||
|
"""Respond to SIGUSR1 by reloading the wallpaper."""
|
||||||
|
wallpaper.animate_new()
|
||||||
|
|
||||||
def alt_tab(msg):
|
def alt_tab(msg):
|
||||||
"""When Alt+Tab or Alt+Shift+Tab are pressed, call this to set the active alt-tab window."""
|
"""When Alt+Tab or Alt+Shift+Tab are pressed, call this to set the active alt-tab window."""
|
||||||
global tabbing, new_focused, alttab
|
global tabbing, new_focused, alttab
|
||||||
@ -1087,6 +1146,10 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
panel.draw()
|
panel.draw()
|
||||||
|
|
||||||
|
signal.signal(signal.SIGUSR1, reload_wallpaper)
|
||||||
|
with open('/tmp/.wallpaper.pid','w') as f:
|
||||||
|
f.write(str(os.getpid())+'\n')
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
# Poll for events.
|
# Poll for events.
|
||||||
msg = yutani.yutani_ctx.poll()
|
msg = yutani.yutani_ctx.poll()
|
||||||
|
Loading…
Reference in New Issue
Block a user