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) { 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;
} }
} }

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. 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()