Support wallpaper switching and fix up select-wallpaper

This commit is contained in:
Kevin Lange 2017-01-09 13:55:10 +09:00
parent dd823cd835
commit 2adc4fefec
2 changed files with 81 additions and 49 deletions

View File

@ -123,44 +123,13 @@ static void redraw(void) {
static int find_wallpaper_pid(void) {
DIR * dirp = opendir("/proc");
FILE * f = fopen("/tmp/.wallpaper.pid","r");
int out_pid = 0;
/* Read the entries in the directory */
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);
if (f) {
fscanf(f, "%d",&out_pid);
}
closedir(dirp);
return out_pid;
}
sprite_t * load_wallpaper(char * file) {
@ -304,7 +273,7 @@ static void button_prev(struct button * this) {
} else {
selected_wallpaper = selected_wallpaper->prev;
if (!selected_wallpaper) {
selected_wallpaper = wallpapers->head;
selected_wallpaper = wallpapers->tail;
}
}

View File

@ -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.
"""
import configparser
import math
import os
import signal
import sys
import time
import os
import cairo
@ -148,7 +150,7 @@ class LogOutWidget(BaseWidget):
self.hilighted = False
def mouse_action(self, msg):
if msg.command == 0:
if msg.command == yutani.MouseEvent.CLICK:
yctx.session_end()
return False
@ -211,7 +213,7 @@ class VolumeWidget(BaseWidget):
self.set_volume()
def mouse_action(self, msg):
if msg.command == 0:
if msg.command == yutani.MouseEvent.CLICK:
if self.muted:
self.muted = False
self.volume = self.previous_volume
@ -223,10 +225,10 @@ class VolumeWidget(BaseWidget):
self.set_volume()
return True
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()
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()
return True
@ -295,7 +297,7 @@ class WindowListWidget(BaseWidget):
previously_hovered = self.hovered
if hovered_index < len(windows):
self.hovered = windows[hovered_index].wid
if msg.command == 0:
if msg.command == yutani.MouseEvent.CLICK:
yctx.focus_window(self.hovered)
elif msg.buttons & yutani.MouseButton.BUTTON_RIGHT:
if not menus:
@ -339,7 +341,6 @@ class MenuEntryAction(object):
self.hilight = False
self.window = None
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(1.0,*self.hilight_gradient_bottom,1.0)
@ -386,7 +387,7 @@ class MenuEntryAction(object):
self.tr.draw(window)
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:
self.action(self.data) # Probably like launch_app("terminal")
self.focus_leave()
@ -588,7 +589,10 @@ class ApplicationsMenuWidget(BaseWidget):
MenuEntryAction("RPG Demo","applications-simulation",menu_callback,"game"),
]),
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(),
MenuEntryAction("Help","help",menu_callback,"help-browser"),
@ -607,7 +611,7 @@ class ApplicationsMenuWidget(BaseWidget):
self.font.font_color = self.color
def mouse_action(self,msg):
if msg.command == 0:
if msg.command == yutani.MouseEvent.CLICK:
menu = MenuWindow(self.menu_entries,(0,PANEL_HEIGHT))
@ -776,12 +780,14 @@ class WallpaperIcon(object):
self.hilighted = False
def mouse_action(self, msg):
if msg.command == 0:
if msg.command == yutani.MouseEvent.CLICK:
self.action(self)
class WallpaperWindow(yutani.Window):
"""Manages the desktop wallpaper window."""
fallback = '/usr/share/wallpapers/default'
def __init__(self):
w = yutani.yutani_ctx._ptr.contents.display_width
h = yutani.yutani_ctx._ptr.contents.display_height
@ -791,10 +797,16 @@ class WallpaperWindow(yutani.Window):
self.set_stack(yutani.WindowStackOrder.ZORDER_BOTTOM)
# 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.focused_icon = None
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):
self.animations[icon] = time.time()
@ -804,6 +816,8 @@ class WallpaperWindow(yutani.Window):
self.draw(self.animations.keys())
ditch = []
for icon in self.animations:
if icon == self:
continue
if tick - self.animations[icon] > 0.5:
ditch.append(icon)
for icon in ditch:
@ -831,7 +845,18 @@ class WallpaperWindow(yutani.Window):
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)
def finish_resize(self, msg):
@ -874,7 +899,35 @@ class WallpaperWindow(yutani.Window):
ctx.paint()
ctx.restore()
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_y = 50
@ -886,10 +939,12 @@ class WallpaperWindow(yutani.Window):
last_width = 0
if icon.width > last_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)
offset_y += icon.height
if clear_animation:
del self.animations[self]
self.flip()
@ -1015,6 +1070,10 @@ def finish_alt_tab(msg):
alttab.close()
def reload_wallpaper(signum, frame):
"""Respond to SIGUSR1 by reloading the wallpaper."""
wallpaper.animate_new()
def alt_tab(msg):
"""When Alt+Tab or Alt+Shift+Tab are pressed, call this to set the active alt-tab window."""
global tabbing, new_focused, alttab
@ -1087,6 +1146,10 @@ if __name__ == '__main__':
panel.draw()
signal.signal(signal.SIGUSR1, reload_wallpaper)
with open('/tmp/.wallpaper.pid','w') as f:
f.write(str(os.getpid())+'\n')
while 1:
# Poll for events.
msg = yutani.yutani_ctx.poll()