shithub: patch

Download patch

ref: 08cf9c4f436c3fcc7bfbbf6d3386fddb5f9dea7c
parent: 56dc18887a7df44e90ceea06adb55475cb508593
author: qwx <qwx@sciops.net>
date: Sun May 8 19:19:16 EDT 2022

vdir-tweaks: update

- backwards history
- refresh button
- smooth drawing using backbuffer
- mouse scrolling continues until buttons released
- middle mouse scroll offset centered on mouse position
- keyboard shortcut tweaks

older tweaks:
- different plumbing for dirs
- changes to clicking behavior: buttons and location

--- a/vdir-tweaks
+++ b/vdir-tweaks
@@ -1,9 +1,290 @@
 diff 663d1a8c4432f3cef70466c04699fb6ebaafbc22 uncommitted
+--- a/alert.c
++++ b/alert.c
+@@ -62,7 +62,7 @@
+ 		o = addpt(screen->r.min, Pt((Dx(screen->r)-w)/2, (Dy(screen->r)-h)/2));
+ 		r = Rect(o.x, o.y, o.x+w, o.y+h);
+ 		if(save==nil){
+-			save = allocimage(display, r, b->chan, 0, DNofill);
++			save = allocimage(display, r, screen->chan, 0, DNofill);
+ 			if(save==nil)
+ 				break;
+ 			draw(save, r, b, nil, r.min);
+--- a/icons.h
++++ b/icons.h
+@@ -420,3 +420,181 @@
+ 	0x46, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 	
+ };
++
++uchar backdata[] = {
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00
++};
++
++uchar refdata[] = {
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00
++};
 --- a/vdir.c
 +++ b/vdir.c
-@@ -273,7 +273,7 @@
+@@ -20,6 +20,12 @@
+ 	Slowscroll = 10,
+ };
+ 
++enum{
++	Nback = 64,
++};
++char *backlist[Nback];
++int backp = -1;
++
+ enum
+ {
+ 	Emouse,
+@@ -47,6 +53,8 @@
+ Rectangle homer;
+ Rectangle upr;
+ Rectangle cdr;
++Rectangle refr;
++Rectangle backr;
+ Rectangle newdirr;
+ Rectangle newfiler;
+ Rectangle viewr;
+@@ -60,6 +68,8 @@
+ Image *iup;
+ Image *inewfile;
+ Image *inewfolder;
++Image *iref;
++Image *iback;
+ Image *toolbg;
+ Image *toolfg;
+ Image *viewbg;
+@@ -68,6 +78,7 @@
+ Image *selfg;
+ Image *scrollbg;
+ Image *scrollfg;
++Image *fb;
+ int sizew;
+ int lineh;
+ int nlines;
+@@ -146,8 +157,38 @@
  }
  
+ void
++pushback(void)
++{
++	if(strlen(path) < 1)
++		return;
++	if(backp == Nback-1)
++		memmove(backlist, backlist+1, (Nback-1) * sizeof *backlist);
++	else
++		backp++;
++	if((backlist[backp] = strdup(path)) == nil)
++		sysfatal("strdup: %r");
++}
++
++int
++back(void)
++{
++	char *p;
++
++	if(backp < 0)
++		return 0;
++	p = backlist[backp];
++	backlist[backp] = nil;
++	backp--;
++	strecpy(path, path+sizeof path, p);
++	free(p);
++	loaddirs();
++	return 1;
++}
++
++void
+ up(void)
+ {
++	pushback();
+ 	snprint(path, sizeof path, abspath(path, ".."));
+ 	loaddirs();
+ }
+@@ -157,6 +198,7 @@
+ {
+ 	char newpath[256] = {0};
+ 
++	pushback();
+ 	if(dir == nil)
+ 		snprint(newpath, sizeof path, home);
+ 	else if(dir[0] == '/')
+@@ -273,7 +315,7 @@
+ }
+ 
  int
 -plumbfile(char *path, char *name)
 +plumbfile(char *path, char *name, int isdir)
@@ -10,7 +291,7 @@
  {
  	char *f;
  	int e;
-@@ -280,9 +280,12 @@
+@@ -280,9 +322,12 @@
  
  	f = smprint("%s/%s", path, name);
  	e = access(f, 0)==0;
@@ -26,8 +307,208 @@
  		alert("Error", "File does not exist anymore", nil, mctl, kctl);
  		loaddirs();
  		redraw();
-@@ -588,40 +591,10 @@
- 	else if(m.buttons == 0)
+@@ -346,6 +391,8 @@
+ 	iup    = loadicon(big, updata, sizeof updata);
+ 	inewfile = loadicon(big, newfiledata, sizeof newfiledata);
+ 	inewfolder = loadicon(big, newfolderdata, sizeof newfolderdata);
++	iref    = loadicon(big, refdata, sizeof refdata);
++	iback    = loadicon(big, backdata, sizeof backdata);
+ }
+ 
+ char*
+@@ -366,7 +413,7 @@
+ 
+ 	p->x += Toolpadding;
+ 	r = Rect(p->x, p->y, p->x+16, p->y+16);
+-	draw(screen, r, c, i, ZP);
++	draw(fb, r, c, i, ZP);
+ 	p->x += 16+Toolpadding;
+ 	return r;
+ }
+@@ -379,12 +426,12 @@
+ 
+ 	s = t;
+ 	if(*s && (p.x+stringwidth(font, s)) > n){
+-		p = string(screen, p, i, ZP, font, ellipsis);
++		p = string(fb, p, i, ZP, font, ellipsis);
+ 		while (*s && (p.x+stringwidth(font, s)) > n) s++;
+ 	}
+ 	for( ; *s; s++){
+ 		s += chartorune(&rn, s) - 1;
+-		p = runestringn(screen, p, i, ZP, font, &rn, 1);
++		p = runestringn(fb, p, i, ZP, font, &rn, 1);
+ 	}
+ 	return p;
+ }
+@@ -407,7 +454,7 @@
+ 	p = addpt(viewr.min, Pt(Toolpadding, Toolpadding));
+ 	p.y += n*lineh;
+ 	r = Rpt(p, addpt(p, Pt(Dx(viewr)-2*Toolpadding, lineh)));
+-	draw(screen, r, bg, nil, ZP);
++	draw(fb, r, bg, nil, ZP);
+ 	t = mdate(d);
+ 	snprint(buf, sizeof buf, "%*lld  %s", sizew, d.length, t);
+ 	free(t);
+@@ -414,12 +461,12 @@
+ 	img = (d.qid.type&QTDIR) ? folder : file;
+ 	p.y -= Padding;
+ 	dy = (lineh-12)/2;
+-	draw(screen, Rect(p.x, p.y+dy, p.x+12, p.y+dy+12), fg, img, ZP);
++	draw(fb, Rect(p.x, p.y+dy, p.x+12, p.y+dy+12), fg, img, ZP);
+ 	p.x += 12+4+Padding;
+ 	p.y += Padding;
+ 	p = drawtext(p, fg, d.name, viewr.max.x - stringwidth(font, buf) - 2*Padding - Toolpadding);
+ 	p.x = viewr.max.x - stringwidth(font, buf) - 2*Padding - Toolpadding;
+-	string(screen, p, fg, ZP, font, buf);
++	string(fb, p, fg, ZP, font, buf);
+ }
+ 
+ void
+@@ -440,22 +487,25 @@
+ 	Point p;
+ 	int i, h, y;
+ 
+-	draw(screen, screen->r, viewbg, nil, ZP);
+-	p = addpt(screen->r.min, Pt(0, Toolpadding));
+-	draw(screen, toolr, toolbg, nil, ZP);
+-	line(screen, Pt(toolr.min.x, toolr.max.y), toolr.max, 0, 0, 0, toolfg, ZP);
++	draw(fb, fb->r, viewbg, nil, ZP);
++	p = Pt(0, Toolpadding);
++	draw(fb, toolr, toolbg, nil, ZP);
++	line(fb, Pt(toolr.min.x, toolr.max.y), toolr.max, 0, 0, 0, toolfg, ZP);
+ 	homer = drawbutton(&p, toolfg, ihome);
+ 	cdr = drawbutton(&p, toolfg, icd);
++	backr = drawbutton(&p, toolfg, iback);
+ 	upr = drawbutton(&p, toolfg, iup);
++	refr = drawbutton(&p, toolfg, iref);
++
+ 	p.x += Toolpadding;
+ 	p.y = toolr.min.y + (Toolpadding+16+Toolpadding-font->height)/2;
+ 	pathr = Rect(p.x, p.y, p.x + stringwidth(font, path), p.y + font->height);
+-	p = drawtext(p, toolfg, path, screen->r.max.x - 2*(Toolpadding+16+Toolpadding));
+-	p.x = screen->r.max.x - 2*(Toolpadding+16+Toolpadding);
+-	p.y = screen->r.min.y + Toolpadding;
++	p = drawtext(p, toolfg, path, fb->r.max.x - 2*(Toolpadding+16+Toolpadding));
++	p.x = fb->r.max.x - 2*(Toolpadding+16+Toolpadding);
++	p.y = fb->r.min.y + Toolpadding;
+ 	newdirr = drawbutton(&p, toolfg, inewfolder);
+ 	newfiler = drawbutton(&p, toolfg, inewfile);
+-	draw(screen, scrollr, scrollbg, nil, ZP);
++	draw(fb, scrollr, scrollbg, nil, ZP);
+ 	if(ndirs>0){
+ 		h = ((double)nlines/ndirs)*Dy(scrollr);
+ 		y = ((double)offset/ndirs)*Dy(scrollr);
+@@ -462,10 +512,11 @@
+ 		scrposr = Rect(scrollr.min.x, scrollr.min.y+y, scrollr.max.x-1, scrollr.min.y+y+h);
+ 	}else
+ 		scrposr = Rect(scrollr.min.x, scrollr.min.y, scrollr.max.x-1, scrollr.max.y);
+-	draw(screen, scrposr, scrollfg, nil, ZP);
++	draw(fb, scrposr, scrollfg, nil, ZP);
+ 	for(i = 0; i<nlines && offset+i<ndirs; i++){
+ 		drawdir(i, 0);
+ 	}
++	draw(screen, screen->r, fb, nil, ZP);
+ 	flushimage(display, 1);
+ }
+ 
+@@ -506,18 +557,42 @@
+ }
+ 
+ void
++scroll(Mouse m)
++{
++	int dy;
++
++	if(m.buttons & 1){
++		dy = 1+nlines*((double)(m.xy.y - scrollr.min.y)/Dy(scrollr));
++		scrollup(dy);
++	}else if(m.buttons & 2){
++		if(nlines<ndirs){
++			offset = scrollclamp((m.xy.y-Dy(scrposr)/2 - (scrollr.min.y)) * ndirs/Dy(scrollr));
++			redraw();
++		}
++	}else if(m.buttons & 4){
++		dy = 1+nlines*((double)(m.xy.y - scrollr.min.y)/Dy(scrollr));
++		scrolldown(dy);
++	}
++}
++
++void
+ evtresize(void)
+ {
+ 	if(getwindow(display, Refnone)<0)
+ 		sysfatal("cannot reattach: %r");
+ 	lineh = Padding+font->height+Padding;
+-	toolr = screen->r;
++	freeimage(fb);
++	if((fb = allocimage(display,
++		Rect(0,0,Dx(screen->r),Dy(screen->r)),
++		screen->chan, 0, DNofill)) == nil)
++		sysfatal("allocimage: %r");
++	toolr = fb->r;
+ 	toolr.max.y = toolr.min.y+16+2*Toolpadding;
+-	scrollr = screen->r;
++	scrollr = fb->r;
+ 	scrollr.min.y = toolr.max.y+1;
+ 	scrollr.max.x = scrollr.min.x + Scrollwidth;
+ 	scrollr = insetrect(scrollr, 1);
+-	viewr = screen->r;
++	viewr = fb->r;
+ 	viewr.min.x += Scrollwidth;
+ 	viewr.min.y = toolr.max.y+1;
+ 	nlines = Dy(viewr)/lineh;
+@@ -542,13 +617,21 @@
+ 		cd(nil);
+ 		redraw();
+ 		break;
++	case Kesc:
++		loaddirs();
++		redraw();
++		break;
+ 	case Kup:
+ 		up();
+ 		redraw();
+ 		break;
+-	case 0x20:
+-		plumbsendtext(plumbfd, "vdir", nil, nil, path);
++	case Kbs:
++		back();
++		redraw();
+ 		break;
++	case 0x0a:
++		plumbsendtext(plumbfd, "vdirw", nil, nil, path);
++		break;
+ 	}
+ }
+ 
+@@ -557,9 +640,8 @@
+ {
+ 	Point p;
+ 
+-	p = screen->r.min;
+-	p.x += (Dx(screen->r)-stringwidth(font, text)-4)/2;
+-	p.y += (Dy(screen->r)-font->height-4)/2;
++	p.x = (Dx(fb->r)-stringwidth(font, text)-4)/2;
++	p.y = (Dy(fb->r)-font->height-4)/2;
+ 	return p;
+ }
+ 
+@@ -579,63 +661,36 @@
+ void
+ evtmouse(Mouse m)
+ {
+-	int n, dy;
++	int n;
+ 	Dir d;
+ 	char buf[256] = {0};
+ 
+-	if(oldbuttons == 0 && m.buttons != 0 && ptinrect(m.xy, scrollr))
++	m.xy = subpt(m.xy, screen->r.min);
++	if(m.buttons != 0 && (ptinrect(m.xy, scrollr) || scrolling)){
+ 		scrolling = 1;
+-	else if(m.buttons == 0)
++		scroll(m);
++	}else
  		scrolling = 0;
  
 -	if(m.buttons&1){
@@ -64,14 +545,24 @@
 -		if(scrolling){
 -			dy = 1+nlines*((double)(m.xy.y - scrollr.min.y)/Dy(scrollr));
 -			scrolldown(dy);
+-		}else if(ptinrect(m.xy, homer)){
 +	if(m.buttons&1 && oldbuttons == 0){
-+ 		if(scrolling){
-+ 			dy = 1+nlines*((double)(m.xy.y - scrollr.min.y)/Dy(scrollr));
-+ 			scrollup(dy);
- 		}else if(ptinrect(m.xy, homer)){
++		if(ptinrect(m.xy, homer)){
  			cd(nil);
  			redraw();
-@@ -634,8 +607,6 @@
+ 		}else if(ptinrect(m.xy, upr)){
+ 			up();
+ 			redraw();
+-		}else if(ptinrect(m.xy, cdr)){
++		}else if(ptinrect(m.xy, refr)){
++			loaddirs();
++			redraw();
++		}else if(ptinrect(m.xy, backr)){
++			if(back())
++				redraw();
++		}else if(ptinrect(m.xy, cdr) || ptinrect(m.xy, pathr)){
+ 			m.xy = cept("Go to directory");
+ 			if(enter("Go to directory", buf, sizeof buf, mctl, kctl, nil)>0){
  				cd(buf);
  				redraw();
  			}
@@ -80,7 +571,7 @@
  		}else if(ptinrect(m.xy, newdirr)){
  			m.xy = cept("Create directory");
  			if(enter("Create directory", buf, sizeof buf, mctl, kctl, nil)>0){
-@@ -656,10 +627,47 @@
+@@ -656,10 +711,39 @@
  			if(d.qid.type & QTDIR){
  				cd(d.name);
  				redraw();
@@ -88,16 +579,16 @@
 -				if(plumbfile(path, d.name))
 -					flash(n);
  			}
-+ 		}
++		}
 +	}else if(m.buttons&2 && oldbuttons == 0){
-+ 		if(ptinrect(m.xy, viewr)){
-+ 			n = indexat(m.xy);
-+ 			if(n==-1)
-+ 				return;
-+ 			d = dirs[offset+n];
++		if(ptinrect(m.xy, viewr)){
++			n = indexat(m.xy);
++			if(n==-1)
++				return;
++			d = dirs[offset+n];
 +			menu2.lasthit = 0;
-+ 			switch(menuhit(2, mctl, &menu2, nil)){
-+ 			case Mdelete:
++			switch(menuhit(2, mctl, &menu2, nil)){
++			case Mdelete:
 +				rm(d.name);
 +				redraw();
 +				break;
@@ -109,17 +600,9 @@
 +				}
 +				break;
 +			}
-+		}else if(scrolling){
-+			if(nlines<ndirs){
-+				offset = scrollclamp((m.xy.y - scrollr.min.y) * ndirs/Dy(scrollr));
-+				redraw();
-+			}
 +		}
 +	}if((m.buttons&4) && oldbuttons == 0){
-+		if(scrolling){
-+			dy = 1+nlines*((double)(m.xy.y - scrollr.min.y)/Dy(scrollr));
-+			scrolldown(dy);
-+		}else if(ptinrect(m.xy, pathr)){
++		if(ptinrect(m.xy, pathr)){
 +			plumbsendtext(plumbfd, "vdirw", nil, nil, path);
 +		}else if(ptinrect(m.xy, viewr)){
 +			n = indexat(m.xy);