diff --git a/README.html b/README.html
index 40db233..0f78c05 100644
--- a/README.html
+++ b/README.html
@@ -219,7 +219,6 @@ alt="typing" />
imlib2
-- Only a dependency if X11 support is enabled.
- Used for image support, can be disabled during compile time.
libXinerama
diff --git a/README.md b/README.md
index 3c7ef71..47600fa 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,6 @@ can be themed to look identical to dmenu.
- libXrender
- For X11 support, which is optional.
- imlib2
- - Only a dependency if X11 support is enabled.
- Used for image support, can be disabled during compile time.
- libXinerama
- For X11 support, which is optional.
diff --git a/docs/docs.md b/docs/docs.md
index 1a5fc90..a8abd9f 100644
--- a/docs/docs.md
+++ b/docs/docs.md
@@ -713,7 +713,6 @@ These are the default keybinds. You can generate these yourself from a
| 0 | Shift | equal | setimgsize | +100 |
| 0 | Shift | minus | setimgsize | -100 |
| 0 | Shift | 0 | defaultimg | 0 |
-| 0 | 0 | r | rotateimg | 0 |
| 0 | 0 | o | setimgpos | +1 |
| 0 | Ctrl | 1 | setimggaps | -1 |
| 0 | Ctrl | 2 | setimggaps | +1 |
diff --git a/docs/spmenu.conf b/docs/spmenu.conf
index aa59040..90d044a 100644
--- a/docs/spmenu.conf
+++ b/docs/spmenu.conf
@@ -440,13 +440,6 @@ spmenu = {
function = "defaultimg";
argument = "0";
},
- // r: Rotate image
- { mode = 0;
- modifier = "None";
- key = "r";
- function = "rotateimg";
- argument = "0";
- },
// o: Toggle image position
{ mode = 0;
modifier = "None";
diff --git a/keybinds.h b/keybinds.h
index 7884114..8b7fde1 100644
--- a/keybinds.h
+++ b/keybinds.h
@@ -36,7 +36,6 @@ static Key keys[] = {
{ 0, Shift, XK_equal, setimgsize, {.i = +100 } },
{ 0, Shift, XK_minus, setimgsize, {.i = -100 } },
{ 0, Shift, XK_0, defaultimg, {0} },
- { 0, 0, XK_r, rotateimg, {0} },
{ 0, 0, XK_o, setimgpos, {.i = +1 } },
{ 0, Ctrl, XK_1, setimggaps, {.i = -1 } },
{ 0, Ctrl, XK_2, setimggaps, {.i = +1 } },
@@ -113,7 +112,6 @@ static WlKey wl_keys[] = {
{ 0, WL_Shift, XKB_KEY_equal, setimgsize, {.i = +100 } },
{ 0, WL_Shift, XKB_KEY_minus, setimgsize, {.i = -100 } },
{ 0, WL_Shift, XKB_KEY_0, defaultimg, {0} },
- { 0, WL_None, XKB_KEY_r, rotateimg, {0} },
{ 0, WL_None, XKB_KEY_o, setimgpos, {.i = +1 } },
{ 0, WL_Ctrl, XKB_KEY_1, setimggaps, {.i = -1 } },
{ 0, WL_Ctrl, XKB_KEY_2, setimggaps, {.i = +1 } },
diff --git a/libs/arg.c b/libs/arg.c
index a996b16..33dc95f 100644
--- a/libs/arg.c
+++ b/libs/arg.c
@@ -415,17 +415,6 @@ void setimggaps(Arg *arg) {
#endif
}
-void rotateimg(Arg *arg) {
-#if USEIMAGE
-
- if (!image || hideimage) return;
-
- rotation += arg->i ? arg->i : 1;
-
- drawmenu();
-#endif
-}
-
void toggleimg(Arg *arg) {
#if USEIMAGE
diff --git a/libs/arg.h b/libs/arg.h
index 0848870..c54da36 100644
--- a/libs/arg.h
+++ b/libs/arg.h
@@ -35,7 +35,6 @@ static void setimgsize(Arg *arg);
static void toggleimg(Arg *arg);
static void togglefullimg(Arg *arg);
static void defaultimg(Arg *arg);
-static void rotateimg(Arg *arg);
static void flipimg(Arg *arg);
static void setimgpos(Arg *arg);
static void setimggaps(Arg *arg);
diff --git a/libs/conf/config.h b/libs/conf/config.h
index 5aca5b1..4c1e045 100644
--- a/libs/conf/config.h
+++ b/libs/conf/config.h
@@ -378,7 +378,6 @@ static FuncList fl[] = {
{ "toggleimg", toggleimg },
{ "togglefullimg", togglefullimg },
{ "defaultimg", defaultimg },
- { "rotateimg", rotateimg },
{ "flipimg", flipimg },
{ "setimgpos", setimgpos },
{ "setimgpos", setimgpos },
diff --git a/libs/draw.c b/libs/draw.c
index 910af7d..1572c2a 100644
--- a/libs/draw.c
+++ b/libs/draw.c
@@ -286,7 +286,7 @@ int drawitem(int x, int y, int w) {
// draw image first
#if USEIMAGE
- if (!hideimage && longestedge != 0 && !protocol) { // TODO: wayland image support
+ if (!hideimage && longestedge != 0) {
rx = ox;
rx += MAX((imagegaps * 2) + imagewidth + menumarginh, indentitems ? x : 0);
} else
@@ -520,10 +520,12 @@ void drawmenu(void) {
wl_surface_attach(state.surface, state.buffer, 0, 0);
wl_surface_damage(state.surface, 0, 0, state.width, state.height);
wl_surface_commit(state.surface);
+
+ drawimage();
} else {
drawmenu_layer();
}
-#else
+#elif USEX
drawmenu_layer();
#endif
}
@@ -627,6 +629,7 @@ void drawmenu_layer(void) {
}
#if USEX
+ drawimage();
drw_map(drw, win, 0, 0, mw, mh);
#endif
}
diff --git a/libs/img.c b/libs/img.c
index 7bba09e..f7729eb 100644
--- a/libs/img.c
+++ b/libs/img.c
@@ -12,11 +12,11 @@ void setimagesize(int width, int height) {
oih = imageheight;
oiw = imagewidth;
+ drawimage();
+
imageheight = height;
imagewidth = width;
- drawimage();
-
needredraw = 0;
if (!image) {
@@ -46,11 +46,6 @@ void flipimage(void) {
}
}
-void rotateimage(void) {
- rotation %= 4;
- imlib_image_orientate(rotation);
-}
-
void cleanupimage(void) {
if (image) { // free image using imlib2
imlib_free_image();
@@ -77,8 +72,6 @@ void drawimage(void) {
} else if ((!sel || !sel->image) && image) { // free image
cleanupimage();
} if (image && longestedge && width && height) { // render the image
- // rotate and flip, will return if we don't need to
- rotateimage();
flipimage();
int leftmargin = imagegaps; // gaps between image and menu
@@ -97,9 +90,9 @@ void drawimage(void) {
wta += menumarginv;
if (mh != bh + height + leftmargin * 2 - wtr && !fullscreen) { // menu height cannot be smaller than image height
- resizetoimageheight(height);
+ resizetoimageheight(width, height);
} else if (mh != bh + height + leftmargin * 2 - wtr && fullscreen) {
- resizetoimageheight(height-bh);
+ resizetoimageheight(width-bh, height-bh);
}
// we're covering all the area
@@ -107,20 +100,23 @@ void drawimage(void) {
xta = wta = wtr = leftmargin = 0;
}
- // render image
+ drw_set_img(drw, imlib_image_get_data(), width, height);
+
+ // render image on X11
if (!imageposition && image) { // top mode = 0
if (height > width)
width = height;
- imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, wta+leftmargin);
+
+ drw_img(drw, leftmargin+(imagewidth-width)/2+xta, wta+leftmargin);
} else if (imageposition == 1 && image) { // bottom mode = 1
if (height > width)
width = height;
- imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, mh-height-leftmargin);
+ drw_img(drw, leftmargin+(imagewidth-width)/2+xta, mh-height-leftmargin);
} else if (imageposition == 2 && image) { // center mode = 2
- imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, (mh-wta-height)/2+wta);
+ drw_img(drw, leftmargin+(imagewidth-width)/2+xta, (mh-wta-height)/2+wta);
} else if (image) { // top center
int minh = MIN(height, mh-bh-leftmargin*2);
- imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, (minh-height)/2+wta+leftmargin);
+ drw_img(drw, leftmargin+(imagewidth-width)/2+xta, (minh-height)/2+wta+leftmargin);
}
}
@@ -131,18 +127,12 @@ void drawimage(void) {
}
}
-#if USEX
void setimageopts(void) {
imlib_set_cache_size(8192 * 1024);
imlib_context_set_blend(1);
imlib_context_set_dither(1);
imlib_set_color_usage(128);
- imlib_context_set_display(dpy);
- imlib_context_set_visual(visual);
- imlib_context_set_colormap(cmap);
- imlib_context_set_drawable(win);
}
-#endif
void createifnexist(const char *dir) {
// exists, so return
@@ -337,8 +327,25 @@ void jumptoindex(unsigned int index) {
}
}
-void resizetoimageheight(int imageheight) {
+void resizetoimageheight(int imagewidth, int imageheight) {
+ //int ih = imageheight;
+ int ih = imlib_image_get_height();
+
#if USEX
+ if (!protocol) {
+ resizetoimageheight_x11(ih);
+ } else {
+#if USEWAYLAND
+ resizetoimageheight_wl(ih);
+#endif
+ }
+#elif USEWAYLAND
+ resizetoimageheight_wl(ih);
+#endif
+}
+
+#if USEX
+void resizetoimageheight_x11(int imageheight) {
int omh = mh, olines = lines;
lines = reallines;
int wtr = 0;
@@ -447,9 +454,69 @@ void resizetoimageheight(int imageheight) {
jumptoindex(i);
}
- drawmenu();
-#endif
+ drawmenu_layer();
}
+#endif
+
+#if USEWAYLAND
+void resizetoimageheight_wl(int imageheight) {
+ int omh = mh, olines = lines;
+ lines = reallines;
+ int wtr = 0;
+
+ if (lines * bh < imageheight + imagegaps * 2) {
+ lines = (imageheight + imagegaps * 2) / bh;
+ }
+
+ if (hideprompt && hideinput && hidemode && hidematchcount) {
+ wtr = bh;
+ }
+
+ mh = MAX((lines + 1) * bh + 2 * menumarginv, ((lines + 1) * bh) - wtr + 2 * menumarginv);
+
+ if (mh - bh < imageheight + imagegaps * 2) {
+ mh = (imageheight + imagegaps * 2 + bh) - wtr + 2 * menumarginv;
+ }
+
+ if (omh == mh) {
+ return;
+ }
+
+ if (olines != lines) {
+ struct item *item;
+ unsigned int i = 1;
+
+ // walk through all matches
+ for (item = matches; item && item != sel; item = item->right)
+ ++i;
+
+ jumptoindex(i);
+ }
+
+ state.width = mw;
+ state.height = mh;
+
+ state.buffer = create_buffer(&state);
+
+ if (drw == NULL) {
+ die("spmenu: drw == NULL");
+ }
+
+ if (state.buffer == NULL) {
+ die("state.buffer == null");
+ }
+
+ set_layer_size(&state, state.width, state.height);
+ drw_create_surface_wl(drw, state.data, state.width, state.height);
+
+ drawmenu();
+
+ wl_surface_set_buffer_scale(state.surface, 1);
+ wl_surface_attach(state.surface, state.buffer, 0, 0);
+ wl_surface_damage(state.surface, 0, 0, state.width, state.height);
+ wl_surface_commit(state.surface);
+}
+#endif
void store_image_vars(void) {
longestedge = MAX(imagewidth, imageheight);
diff --git a/libs/img.h b/libs/img.h
index 714275f..399a8e3 100644
--- a/libs/img.h
+++ b/libs/img.h
@@ -7,16 +7,19 @@
#include
static void setimagesize(int width, int height);
-#if USEX
static void setimageopts(void);
-#endif
static void cleanupimage(void);
static void drawimage(void);
-static void rotateimage(void);
static void flipimage(void);
static void loadimage(const char *file, int *width, int *height);
static void loadimagecache(const char *file, int *width, int *height);
-static void resizetoimageheight(int imageheight);
+static void resizetoimageheight(int imagewidth, int imageheight);
+#if USEWAYLAND
+static void resizetoimageheight_wl(int imageheight);
+#endif
+#if USEX
+static void resizetoimageheight_x11(int imageheight);
+#endif
static void store_image_vars(void);
static Imlib_Image image = NULL;
diff --git a/libs/libdrw/drw.c b/libs/libdrw/drw.c
index 97acadc..f95d9ac 100644
--- a/libs/libdrw/drw.c
+++ b/libs/libdrw/drw.c
@@ -415,6 +415,28 @@ void drw_cur_free(Drw *drw, Cur *cursor) {
#endif
}
+void drw_set_img(Drw *drw, void *data, int w, int h) {
+ if (!w || !h || !drw) {
+ return;
+ }
+
+ drw->img_data = data;
+ drw->img_surface = cairo_image_surface_create_for_data(drw->img_data, CAIRO_FORMAT_ARGB32, w, h, w * 4);
+}
+
+void drw_img(Drw *drw, int x, int y) {
+ if (!drw) {
+ return;
+ }
+
+ cairo_set_operator(drw->d, CAIRO_OPERATOR_OVER);
+
+ cairo_set_source_surface(drw->d, drw->img_surface, x, y);
+ cairo_paint(drw->d);
+
+ cairo_set_source_surface(drw->d, drw->surface, drw->w, drw->h);
+}
+
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup) {
unsigned int tmp = 0;
if (drw && drw->font && text && n)
diff --git a/libs/libdrw/drw.h b/libs/libdrw/drw.h
index 70d0bf0..71c7beb 100644
--- a/libs/libdrw/drw.h
+++ b/libs/libdrw/drw.h
@@ -24,18 +24,25 @@ typedef struct {
Window root;
Visual *visual;
unsigned int depth;
+ void *img_data;
void *data;
Colormap cmap;
Drawable drawable;
GC gc;
Fnt *font;
cairo_surface_t *surface;
+ cairo_surface_t *img_surface;
cairo_t *d;
+ cairo_t *img_d;
} Drw;
/* Cairo color convertion */
void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha);
+/* Cairo image drawing */
+void drw_img(Drw *drw, int x, int y);
+void drw_set_img(Drw *drw, void *data, int w, int h);
+
/* Drawable abstraction */
Drw *drw_create_x11(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol);
Drw *drw_create_wl(int protocol);
diff --git a/libs/wl/wayland.h b/libs/wl/wayland.h
index 4b361d7..3775c8f 100644
--- a/libs/wl/wayland.h
+++ b/libs/wl/wayland.h
@@ -145,6 +145,7 @@ static int set_exclusive_zone(struct state *state, unsigned int val);
static int set_keyboard(struct state *state, int interactivity);
static int add_layer_listener(struct state *state);
static int set_visible_layer(struct state *state);
+struct wl_buffer *create_buffer(struct state *state);
/* Set to 0 if the connection was successful
* You can use this for say, X11 compatibility mode.
diff --git a/libs/x11/client.c b/libs/x11/client.c
index 04a1a95..f283a87 100644
--- a/libs/x11/client.c
+++ b/libs/x11/client.c
@@ -93,7 +93,7 @@ void resizeclient_x11(void) {
// resize client to image height
#if USEIMAGE
- if (image) resizetoimageheight(imageheight);
+ if (image) resizetoimageheight(imagewidth, imageheight);
#endif
mh = (lines + 1) * bh + 2 * menumarginv;
diff --git a/libs/x11/event.c b/libs/x11/event.c
index 297aa47..064c7bf 100644
--- a/libs/x11/event.c
+++ b/libs/x11/event.c
@@ -1,7 +1,6 @@
/* See LICENSE file for copyright and license details. */
void eventloop_x11(void) {
XEvent ev;
- int noimg = 0;
while (!XNextEvent(dpy, &ev)) {
if (XFilterEvent(&ev, None))
@@ -15,7 +14,6 @@ void eventloop_x11(void) {
exit(1);
case ButtonPress:
buttonpress_x11(&ev);
- noimg = 0;
break;
case MotionNotify: // currently does nothing
break;
@@ -35,7 +33,6 @@ void eventloop_x11(void) {
}
keypress_x11(&ev);
- noimg = 1;
break;
case SelectionNotify: // paste selection
if (ev.xselection.property == utf8)
@@ -48,7 +45,6 @@ void eventloop_x11(void) {
case KeyRelease:
getcapsstate();
drawmenu();
- noimg = 0;
break;
}
@@ -67,13 +63,5 @@ void eventloop_x11(void) {
drawmenu();
}
}
-
- // redraw image on X11 event
- if (!noimg)
-#if USEIMAGE
- drawimage();
-#else
- ;
-#endif
}
}
diff --git a/libs/x11/init.c b/libs/x11/init.c
index 800e554..d047109 100644
--- a/libs/x11/init.c
+++ b/libs/x11/init.c
@@ -10,7 +10,7 @@ void setupdisplay_x11(void) {
// resize client to image height if deemed necessary
#if USEIMAGE
- if (image) resizetoimageheight(imageheight);
+ if (image) resizetoimageheight(imagewidth, imageheight);
#endif
// set prompt width based on prompt size
diff --git a/meson.build b/meson.build
index 0cf41a5..96f1cb5 100644
--- a/meson.build
+++ b/meson.build
@@ -57,7 +57,7 @@ if get_option('wayland')
run_command('scripts/make/generate-headers.sh', check : false)
endif
-if get_option('imlib2') and get_option('openssl') and get_option('x11')
+if get_option('imlib2') and get_option('openssl')
project_dependencies += [ dependency('imlib2') ]
project_dependencies += [ dependency('openssl') ]
build_args += [ '-DIMAGE' ]
diff --git a/spmenu.1 b/spmenu.1
index 42aa100..8481952 100644
--- a/spmenu.1
+++ b/spmenu.1
@@ -1001,17 +1001,6 @@ T{
T}@T{
0
T}@T{
-r
-T}@T{
-rotateimg
-T}@T{
-0
-T}
-T{
-0
-T}@T{
-0
-T}@T{
o
T}@T{
setimgpos
diff --git a/spmenu.c b/spmenu.c
index 6ef8998..20f3cb6 100644
--- a/spmenu.c
+++ b/spmenu.c
@@ -153,7 +153,6 @@ struct item {
// image globals
#if USEIMAGE
static int flip = 0;
-static int rotation = 0;
static int needredraw = 1;
static int longestedge = 0;
static int imagew = 0;
@@ -495,7 +494,7 @@ void handle(void) {
}
loadhistory(); // read history entries
-#if USEX
+#if USEIMAGE
store_image_vars();
#endif
diff --git a/spmenu.html b/spmenu.html
index 8806d2d..7c7f0eb 100644
--- a/spmenu.html
+++ b/spmenu.html
@@ -1186,284 +1186,277 @@ a keybinds.h
using
0 |
0 |
-r |
-rotateimg |
-0 |
-
-
-0 |
-0 |
o |
setimgpos |
+1 |
-
+
0 |
Ctrl |
1 |
setimggaps |
-1 |
-
+
0 |
Ctrl |
2 |
setimggaps |
+1 |
-
+
0 |
0 |
1 |
setimggaps |
-10 |
-
+
0 |
0 |
2 |
setimggaps |
+10 |
-
+
0 |
Shift |
1 |
setimggaps |
-100 |
-
+
0 |
Shift |
2 |
setimggaps |
+100 |
-
+
0 |
0 |
t |
toggleimg |
0 |
-
+
0 |
0 |
f |
togglefullimg |
0 |
-
+
0 |
0 |
p |
paste |
2 |
-
+
0 |
0 |
h |
flipimg |
1 |
-
+
0 |
0 |
v |
flipimg |
0 |
-
+
0 |
0 |
k |
moveup |
0 |
-
+
0 |
0 |
j |
movedown |
0 |
-
+
0 |
0 |
h |
moveleft |
0 |
-
+
0 |
0 |
l |
moveright |
0 |
-
+
0 |
Ctrl |
u |
moveup |
5 |
-
+
0 |
Ctrl |
d |
movedown |
5 |
-
+
0 |
Ctrl |
k |
setlines |
+1 |
-
+
0 |
Ctrl |
j |
setlines |
-1 |
-
+
0 |
Ctrl+Alt+Shift |
k |
setlines |
+5 |
-
+
0 |
Ctrl+Alt+Shift |
j |
setlines |
-5 |
-
+
0 |
Ctrl |
h |
setcolumns |
+1 |
-
+
0 |
Ctrl |
l |
setcolumns |
-1 |
-
+
0 |
Ctrl+Alt+Shift |
h |
setcolumns |
+5 |
-
+
0 |
Ctrl+Alt+Shift |
l |
setcolumns |
-5 |
-
+
0 |
0 |
u |
togglehighlight |
0 |
-
+
0 |
Ctrl+Shift |
h |
viewhist |
0 |
-
+
0 |
0 |
d |
clear |
0 |
-
+
0 |
Shift |
d |
clearins |
0 |
-
+
0 |
0 |
Escape |
quit |
0 |
-
+
0 |
0 |
Home |
movestart |
0 |
-
+
0 |
0 |
End |
moveend |
0 |
-
+
0 |
0 |
g |
movestart |
0 |
-
+
0 |
Shift |
g |
moveend |
0 |
-
+
0 |
0 |
Next |
movenext |
0 |
-
+
0 |
0 |
Prior |
moveprev |
0 |
-
+
0 |
Alt |
p |
navhistory |
-1 |
-
+
0 |
Alt |
n |
navhistory |
+1 |
-
+
1 |
0 |
Escape |