diff --git a/man/feh.pre b/man/feh.pre
index 5635fe813d8fbbe6ef5bda3c8c2f28eb91fcd4ec..b40510efb88598e6be521b872b90fca5e9430661 100644
--- a/man/feh.pre
+++ b/man/feh.pre
@@ -517,66 +517,6 @@ mode.
 .El
 .
 .
-.Sh BUTTON OPTIONS
-.
-.Bl -tag -width indent
-.
-.It Cm -0 , --reload-button Ar int
-.
-Set button to reload the image
-.Pq default: 0 .
-.
-.It Cm -1 , --pan-button Ar int
-.
-Set button to pan the image
-.Pq hold button down and move mouse to move the image .
-When the mouse is not moved, advances to the next image in slideshow mode.
-.Pq default: 1 , usually the left button .
-.
-.It Cm -2 , --zoom-button Ar int
-.
-Set button to enable zoom mode
-.Pq default: 2 , usually the middle button .
-.
-.It Cm -3 , --menu-button Ar int
-.
-Set button to activate the menu.
-.Pq default: 3 , usually the right button .
-.
-.It Cm --menu-ctrl-mask
-.
-Require CTRL+Button for menu activation.
-.
-.It Cm -4 , --prev-button Ar int
-.
-Set button to switch to the previous image in slideshow mode
-.Pq default: 4 , usually Aq mousewheel up .
-.
-.It Cm -5 , --next-button Ar int
-.
-Set button to switch to the next image in slideshow mode
-.Pq default: 5 , usually Aq mousewheel down .
-.
-.It Cm -8 , --rotate-button Ar int
-.
-Use CTRL+Button to rotate the current image
-.Pq default : 2 .
-.
-.It Cm --no-rotate-ctrl-mask
-.
-Don't require CTRL+Button for rotation - just use the button.
-.
-.It Cm -9 , --blur-button Ar int
-.
-Use CTRL+Button for blurring
-.Pq default : 1 .
-.
-.It Cm --no-blur-ctrl-mask
-.
-Don't require CTRL+Button for blurring - just use the button.
-.El
-.
-.
 .Sh MONTAGE MODE OPTIONS
 .
 These additional options can be used for index, montage and
@@ -1167,6 +1107,70 @@ Select highlighted menu item
 .El
 .
 .
+.Sh BUTTONS CONFIG SYNTAX
+.
+This works like the keys config file: the entries are of the form
+.Qq Ar action Op Ar binding .
+.
+.Pp
+.
+Each
+.Ar binding
+is a button name.  It may optionally start with modifiers for things like
+Control, in which case
+.Ar binding
+looks like
+.Ar mod Ns No - Ns Ar button
+.Pq for example "C-1" for Ctrl + Left button .
+.
+.Pp
+.
+For the available modifiers, see
+.Sx KEYS CONFIGURATION SYNTAX .
+.
+.
+.Ss BUTTONS
+.
+In an image window, the following buttons may be used
+.Pq The strings in Bo square brackets Bc are the config action names :
+.
+.Bl -tag -width indent
+.
+.It Bq reload
+.
+Reload current image
+.
+.It 1 Ao left mouse button Ac Bq pan
+.
+pan the current image
+.
+.It 2 Ao middle mouse button Ac Bq zoom
+.
+Zoom the current image
+.
+.It 3 Ao right mouse button Ac Bq menu
+.
+Toggle menu
+.
+.It 4 Ao mousewheel down Ac Bq prev
+.
+Show previous image
+.
+.It 5 Ao mousewheel up Ac Bq next
+.
+Show next image
+.
+.It Ctrl+1 Bq blur
+.
+Blur current image
+.
+.It Ctrl+2 Bq rotate
+.
+Rotate current image
+.
+.El
+.
+.
 .Sh MOUSE ACTIONS
 .
 When viewing an image, by default mouse button 1 pans
diff --git a/src/events.c b/src/events.c
index 2b8abdd6472c666f9df0757b0e129c8a9a64a64f..0d5e07d214cb174903ec582d0a8008737b71fcc5 100644
--- a/src/events.c
+++ b/src/events.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "events.h"
 #include "thumbnail.h"
 
+fehbb buttons;
+
 feh_event_handler *ev_handler[LASTEvent];
 
 static void feh_event_handle_ButtonPress(XEvent * ev);
@@ -41,6 +43,129 @@ static void feh_event_handle_LeaveNotify(XEvent * ev);
 static void feh_event_handle_MotionNotify(XEvent * ev);
 static void feh_event_handle_ClientMessage(XEvent * ev);
 
+static void feh_set_bb(fehbutton *bb, int modifier, char button)
+{
+	bb->modifier = modifier;
+	bb->button = button;
+}
+
+static void feh_set_parse_bb_partial(fehbutton *button, char *binding)
+{
+	char *cur = binding;
+	int mod = 0;
+
+	if (!*binding) {
+		button->button = 0;
+		return;
+	}
+
+	while (cur[1] == '-') {
+		switch (cur[0]) {
+			case 'C':
+				mod |= ControlMask;
+				break;
+			case 'S':
+				mod |= ShiftMask;
+				break;
+			case '1':
+				mod |= Mod1Mask;
+				break;
+			case '4':
+				mod |= Mod4Mask;
+				break;
+			default:
+				weprintf("buttons: invalid modifier %c in \"%s\"", cur[0], binding);
+				break;
+		}
+		cur += 2;
+	}
+
+	button->button = atoi(cur);
+	button->modifier = mod;
+}
+
+void init_buttonbindings(void)
+{
+	char *home = NULL;
+	char *confhome = NULL;
+	char *confpath = NULL;
+	char line[128];
+	char action[32], button[8];
+	struct __fehbutton *cur_bb = NULL;
+	FILE *conf = NULL;
+	int read = 0;
+
+	memset(&buttons, 0, sizeof(buttons));
+
+	feh_set_bb(&buttons.reload, 0, 0);
+	feh_set_bb(&buttons.pan,    0, 1);
+	feh_set_bb(&buttons.zoom,   0, 2);
+	feh_set_bb(&buttons.menu,   0, 3);
+	feh_set_bb(&buttons.prev,   0, 4);
+	feh_set_bb(&buttons.next,   0, 5);
+	feh_set_bb(&buttons.blur,   4, 1);
+	feh_set_bb(&buttons.rotate, 4, 2);
+
+	home = getenv("HOME");
+	if (!home)
+		eprintf("No HOME in environment");
+
+	confhome = getenv("XDG_CONFIG_HOME");
+
+	if (confhome)
+		confpath = estrjoin("/", confhome, "feh/buttons", NULL);
+	else
+		confpath = estrjoin("/", home, ".config/feh/buttons", NULL);
+
+	conf = fopen(confpath, "r");
+
+	free(confpath);
+
+	if (!conf && ((conf = fopen("/etc/feh/buttons", "r")) == NULL))
+		return;
+
+	while (fgets(line, sizeof(line), conf)) {
+		*action = '\0';
+		*button = '\0';
+
+		read = sscanf(line, "%31s %7s\n", (char *) &action, (char *) &button);
+
+		if ((read == EOF) || (read == 0) || (line[0] == '#'))
+			continue;
+
+		if (!strcmp(action, "reload"))
+			cur_bb = &buttons.reload;
+		else if (!strcmp(action, "pan"))
+			cur_bb = &buttons.pan;
+		else if (!strcmp(action, "zoom"))
+			cur_bb = &buttons.zoom;
+		else if (!strcmp(action, "menu"))
+			cur_bb = &buttons.menu;
+		else if (!strcmp(action, "prev"))
+			cur_bb = &buttons.prev;
+		else if (!strcmp(action, "next"))
+			cur_bb = &buttons.next;
+		else if (!strcmp(action, "blur"))
+			cur_bb = &buttons.blur;
+		else if (!strcmp(action, "rotate"))
+			cur_bb = &buttons.rotate;
+		else
+			weprintf("buttons: Invalid action: %s", action);
+
+		if (cur_bb)
+			feh_set_parse_bb_partial(cur_bb, button);
+	}
+	fclose(conf);
+}
+
+static short feh_is_bb(fehbutton *bb, int button, int mod)
+{
+	if ((bb->modifier == mod) && (bb->button == button))
+		return 1;
+	return 0;
+}
+
+
 void feh_event_init(void)
 {
 	int i;
@@ -62,6 +187,7 @@ void feh_event_init(void)
 static void feh_event_handle_ButtonPress(XEvent * ev)
 {
 	winwidget winwid = NULL;
+	int state, button;
 
 	/* get the heck out if it's a mouse-click on the
 	   cover, we'll hide the menus on release */
@@ -74,31 +200,34 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
 		return;
 	}
 
-	if (!opt.no_menus && EV_IS_MENU_BUTTON(ev)) {
+	state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask);
+	button = ev->xbutton.button;
+
+	if (!opt.no_menus && feh_is_bb(&buttons.menu, button, state)) {
 		D(("Menu Button Press event\n"));
 		winwidget_show_menu(winwid);
-	} else if ((ev->xbutton.button == opt.rotate_button)
-		   && (winwid->type != WIN_TYPE_THUMBNAIL)
-		   && ((opt.no_rotate_ctrl_mask)
-		       || (ev->xbutton.state & ControlMask))) {
+
+	} else if (feh_is_bb(&buttons.rotate, button, state)
+		   && (winwid->type != WIN_TYPE_THUMBNAIL)) {
 		opt.mode = MODE_ROTATE;
 		winwid->mode = MODE_ROTATE;
 		D(("rotate starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y));
-	} else if ((ev->xbutton.button == opt.blur_button)
-		   && (winwid->type != WIN_TYPE_THUMBNAIL)
-		   && ((opt.no_blur_ctrl_mask)
-		       || (ev->xbutton.state & ControlMask))) {
+
+	} else if (feh_is_bb(&buttons.blur, button, state)
+		   && (winwid->type != WIN_TYPE_THUMBNAIL)) {
 		opt.mode = MODE_BLUR;
 		winwid->mode = MODE_BLUR;
 		D(("blur starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y));
-	} else if (ev->xbutton.button == opt.pan_button) {
+
+	} else if (feh_is_bb(&buttons.pan, button, state)) {
 		D(("Next button, but could be pan mode\n"));
 		opt.mode = MODE_NEXT;
 		winwid->mode = MODE_NEXT;
 		D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
 		winwid->click_offset_x = ev->xbutton.x - winwid->im_x;
 		winwid->click_offset_y = ev->xbutton.y - winwid->im_y;
-	} else if (ev->xbutton.button == opt.zoom_button) {
+
+	} else if (feh_is_bb(&buttons.zoom, button, state)) {
 		D(("Zoom Button Press event\n"));
 		opt.mode = MODE_ZOOM;
 		winwid->mode = MODE_ZOOM;
@@ -112,17 +241,21 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
 				- winwid->im_x) / winwid->old_zoom;
 		winwid->im_click_offset_y = (winwid->click_offset_y
 				- winwid->im_y) / winwid->old_zoom;
-	} else if (ev->xbutton.button == opt.reload_button) {
+
+	} else if (feh_is_bb(&buttons.reload, button, state)) {
 		D(("Reload Button Press event\n"));
 			feh_reload_image(winwid, 0, 1);
-	} else if (ev->xbutton.button == opt.prev_button) {
+
+	} else if (feh_is_bb(&buttons.prev, button, state)) {
 		D(("Prev Button Press event\n"));
 		if (winwid->type == WIN_TYPE_SLIDESHOW)
 			slideshow_change_image(winwid, SLIDE_PREV, 1);
-	} else if (ev->xbutton.button == opt.next_button) {
+
+	} else if (feh_is_bb(&buttons.next, button, state)) {
 		D(("Next Button Press event\n"));
 		if (winwid->type == WIN_TYPE_SLIDESHOW)
 			slideshow_change_image(winwid, SLIDE_NEXT, 1);
+
 	} else {
 		D(("Received other ButtonPress event\n"));
 	}
@@ -132,6 +265,8 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
 static void feh_event_handle_ButtonRelease(XEvent * ev)
 {
 	winwidget winwid = NULL;
+	int state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask);
+	int button = ev->xbutton.button;
 
 	if (menu_root) {
 		/* if menus are open, close them, and execute action if needed */
@@ -156,7 +291,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev)
 		return;
 	}
 
-	if (ev->xbutton.button == opt.pan_button) {
+	if (feh_is_bb(&buttons.pan, button, state)) {
 		if (opt.mode == MODE_PAN) {
 			D(("Disabling pan mode\n"));
 			opt.mode = MODE_NORMAL;
@@ -186,13 +321,14 @@ static void feh_event_handle_ButtonRelease(XEvent * ev)
 			opt.mode = MODE_NORMAL;
 			winwid->mode = MODE_NORMAL;
 		}
-	} else if ((ev->xbutton.button == opt.rotate_button)
-			|| (ev->xbutton.button == opt.zoom_button)) {
+
+	} else if (feh_is_bb(&buttons.rotate, button, state)
+			|| feh_is_bb(&buttons.zoom, button, state)) {
 		D(("Disabling mode\n"));
 		opt.mode = MODE_NORMAL;
 		winwid->mode = MODE_NORMAL;
 
-		if ((ev->xbutton.button == opt.zoom_button)
+		if ((feh_is_bb(&buttons.zoom, button, state))
 				&& (ev->xbutton.x == winwid->click_offset_x)
 				&& (ev->xbutton.y == winwid->click_offset_y)) {
 			winwid->zoom = 1.0;
@@ -201,9 +337,8 @@ static void feh_event_handle_ButtonRelease(XEvent * ev)
 			winwidget_sanitise_offsets(winwid);
 
 		winwidget_render_image(winwid, 0, 0);
-	} else if ((ev->xbutton.button == opt.blur_button)
-			&& ((opt.no_blur_ctrl_mask)
-				|| (ev->xbutton.state & ControlMask))) {
+
+	} else if (feh_is_bb(&buttons.blur, button, state)) {
 		D(("Disabling Blur mode\n"));
 		opt.mode = MODE_NORMAL;
 		winwid->mode = MODE_NORMAL;
diff --git a/src/events.h b/src/events.h
index 22abaf7d0f7f673206d9c5c3f684471caee8b289..195f268dd2f3805a18b08912029c69e0b6340f6b 100644
--- a/src/events.h
+++ b/src/events.h
@@ -32,6 +32,4 @@ extern feh_event_handler *ev_handler[];
 
 void feh_event_init(void);
 
-#define EV_IS_MENU_BUTTON(ev) ((((ev)->xbutton.button == opt.menu_button) || (opt.menu_button == 0)) && (((!opt.menu_ctrl_mask) && (!((ev)->xbutton.state & ControlMask))) || (((ev)->xbutton.state & ControlMask) && (opt.menu_ctrl_mask))))
-
 #endif
diff --git a/src/feh.h b/src/feh.h
index d4a1ff7ee06117777ef6bb3cf54817f394abab32..550b6f57b8c2a4397e54f2bdce34bd3b81129817 100644
--- a/src/feh.h
+++ b/src/feh.h
@@ -134,6 +134,7 @@ void slideshow_change_image(winwidget winwid, int change, int render);
 void slideshow_pause_toggle(winwidget w);
 char *slideshow_create_name(feh_file * file);
 void init_keyevents(void);
+void init_buttonbindings(void);
 void feh_event_handle_keypress(XEvent * ev);
 void feh_action_run(feh_file * file, char *action);
 char *feh_printf(char *str, feh_file * file);
diff --git a/src/help.raw b/src/help.raw
index e8c848e60ecb195c0116f056c96a7769066a6a72..48c8a709e8dd72e058a6c8659a688bf6ca9fbb90 100644
--- a/src/help.raw
+++ b/src/help.raw
@@ -80,30 +80,6 @@ OPTIONS
  -B, --image-bg STYLE      Set background for transparent images and the like.
                            Accepted values: white, black, default
  -N, --no-menus            Don't load or show any menus.
- -0, --reload-button B     Use button B to reload the image (defaults to 0)
- -1, --pan-button B        Use button B pan the image (hold button down, move
-                           the mouse to move the image around. Advances to the
-                           next image when the mouse is not moved (defaults to
-                           1, usually the left button).
- -2, --zoom-button B       Use button B to zoom the current image in any
-                           mode (defaults to 2, usually the middle button).
- -3, --menu-button B       Click button B to activate the menu in any
-                           mode.  Set to 0 for any button.  This option
-                           is disabled if the -N or --no-menus option is set
-                           (defaults to 3, usually the right button).
-     --menu-ctrl-mask      Require CTRL+Button for menu activation
- -4, --prev-button B       Use button B to switch to the previous image
-                           (defaults to 4, which usually is <mousewheel up>).
- -5, --next-button B       Use button B to switch to the next image
-                           (defaults to 5, which usually is <mousewheel down>).
- -8, --rotate-button B     Use CTRL+Button B to rotate the current image in
-                           any mode (default=2).
-     --no-rotate-ctrl-mask Don't require CTRL+Button for rotation in
-                           any mode -- just use the button (default=off).
- -9, --blur-button B       Use CTRL+Button B to blur the current image in
-                           any mode (default=1).
-     --no-blur-ctrl-mask   Don't require CTRL+Button for blurring in
-                           any mode -- just use the button (default=off).
      --no-xinerama         Disable Xinerama support
      --no-screen-clip      Do not limit window size to screen size
  -Y, --hide-pointer        Hide the pointer
diff --git a/src/keyevents.c b/src/keyevents.c
index 942a88b6c482c0e8bb943aeb4c2fc6be7cb6054e..827ab24ef8c5e042c29fdf194b6fb41b11108f59 100644
--- a/src/keyevents.c
+++ b/src/keyevents.c
@@ -154,7 +154,7 @@ void init_keyevents(void) {
 
 	home = getenv("HOME");
 	if (!home)
-		eprintf("No HOME in environment\n");
+		eprintf("No HOME in environment");
 
 	confhome = getenv("XDG_CONFIG_HOME");
 
diff --git a/src/main.c b/src/main.c
index 12dec52c4880f4ea89686a128d288304983c4f58..5891056afb2e9c3ef8fa0250b2d65993388e8b3d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -47,6 +47,7 @@ int main(int argc, char **argv)
 	if (opt.display) {
 		init_x_and_imlib();
 		init_keyevents();
+		init_buttonbindings();
 	}
 
 	feh_event_init();
diff --git a/src/options.c b/src/options.c
index def17f07dbaaf7717bc9935ae750053a63fb188f..316f62db84027c32a20245827be1d80f4ee78163 100644
--- a/src/options.c
+++ b/src/options.c
@@ -61,19 +61,6 @@ void init_parse_options(int argc, char **argv)
 	opt.menu_bg = estrdup(PREFIX "/share/feh/images/menubg_default.png");
 	opt.menu_style = estrdup(PREFIX "/share/feh/fonts/menu.style");
 
-	opt.reload_button = 0;
-	opt.pan_button = 1;
-	opt.zoom_button = 2;
-	opt.menu_button = 3;
-	opt.menu_ctrl_mask = 0;
-	opt.prev_button = 4;
-	opt.next_button = 5;
-
-	opt.rotate_button = 2;
-	opt.no_rotate_ctrl_mask = 0;
-	opt.blur_button = 1;
-	opt.no_blur_ctrl_mask = 0;
-
 	opt.start_list_at = NULL;
 	opt.jump_on_resort = 1;
 
@@ -315,7 +302,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
 {
 	static char stropts[] =
 		"a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqrR:sS:tT:uUvVwW:xXy:YzZ"
-		"0:1:2:4:5:8:9:.@:^:~:):|:+:";
+		".@:^:~:):|:+:";
 
 	/* (*name, has_arg, *flag, val) See: struct option in getopts.h */
 	static struct option lopts[] = {
@@ -352,9 +339,6 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
 		{"cache-thumbnails", 0, 0, 'P'},
 		{"cycle-once"    , 0, 0, 224},
 		{"no-xinerama"   , 0, 0, 225},
-		{"no-rotate-ctrl-mask", 0, 0, 226},
-		{"no-blur-ctrl-mask", 0, 0, 227},
-		{"menu-ctrl-mask", 0, 0, 228},
 		{"draw-tinted"   , 0, 0, 229},
 
 		{"output"        , 1, 0, 'o'},
@@ -381,14 +365,6 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
 		{"fontpath"      , 1, 0, 'C'},
 		{"menu-bg"       , 1, 0, ')'},
 		{"image-bg"      , 1, 0, 'B'},
-		{"reload-button" , 1, 0, '0'},
-		{"pan-button"    , 1, 0, '1'},
-		{"zoom-button"   , 1, 0, '2'},
-		{"menu-button"   , 1, 0, '3'},
-		{"prev-button"   , 1, 0, '4'},
-		{"next-button"   , 1, 0, '5'},
-		{"rotate-button" , 1, 0, '8'},
-		{"blur-button"   , 1, 0, '9'},
 		{"start-at"      , 1, 0, '|'},
 		{"debug"         , 0, 0, '+'},
 		{"output-dir"    , 1, 0, 'j'},
@@ -631,30 +607,6 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
 			else
 				opt.filelistfile = estrdup(optarg);
 			break;
-		case '0':
-			opt.reload_button = atoi(optarg);
-			break;
-		case '1':
-			opt.pan_button = atoi(optarg);
-			break;
-		case '2':
-			opt.zoom_button = atoi(optarg);
-			break;
-		case '3':
-			opt.menu_button = atoi(optarg);
-			break;
-		case '4':
-			opt.prev_button = atoi(optarg);
-			break;
-		case '5':
-			opt.next_button = atoi(optarg);
-			break;
-		case '8':
-			opt.rotate_button = atoi(optarg);
-			break;
-		case '9':
-			opt.blur_button = atoi(optarg);
-			break;
 		case '|':
 			opt.start_list_at = estrdup(optarg);
 			break;
@@ -746,15 +698,6 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
 		case 225:
 			opt.xinerama = 0;
 			break;
-		case 226:
-			opt.no_rotate_ctrl_mask = 1;
-			break;
-		case 227:
-			opt.no_blur_ctrl_mask = 1;
-			break;
-		case 228:
-			opt.menu_ctrl_mask = 1;
-			break;
 		case 229:
 			opt.text_bg = TEXT_BG_TINTED;
 			break;
diff --git a/src/options.h b/src/options.h
index ae3a707619beb49105111f32fa136d125376924a..f1fe3c41203600ee1368ab1e8cca4866df6b811d 100644
--- a/src/options.h
+++ b/src/options.h
@@ -92,20 +92,6 @@ struct __fehoptions {
 
 	gib_style *menu_style_l;
 
-	unsigned char pan_button;
-	unsigned char zoom_button;
-	unsigned char menu_button;
-	unsigned char menu_ctrl_mask;
-	unsigned char prev_button;
-	unsigned char next_button;
-
-	unsigned char rotate_button;
-	unsigned char blur_button;
-	unsigned char reload_button;
-	unsigned char no_rotate_ctrl_mask;
-	unsigned char no_blur_ctrl_mask;
-	unsigned char no_pan_ctrl_mask;
-
 	int force_aliasing;
 	int thumb_w;
 	int thumb_h;
@@ -199,6 +185,22 @@ struct __fehkb {
 	struct __fehkey reload_plus;
 };
 
+struct __fehbutton {
+	int modifier;
+	char button;
+};
+
+struct __fehbb {
+	struct __fehbutton pan;
+	struct __fehbutton zoom;
+	struct __fehbutton reload;
+	struct __fehbutton prev;
+	struct __fehbutton next;
+	struct __fehbutton menu;
+	struct __fehbutton blur;
+	struct __fehbutton rotate;
+};
+
 void init_parse_options(int argc, char **argv);
 char *feh_string_normalize(char *str);
 
diff --git a/src/structs.h b/src/structs.h
index 3942bc0a4865cd7103f72fe4764d6f6f83b98c47..e1acf2d4c32dcac235948471b31e53f96defac5a 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -36,5 +36,7 @@ typedef _winwidget *winwidget;
 typedef struct __fehoptions fehoptions;
 typedef struct __fehkey fehkey;
 typedef struct __fehkb fehkb;
+typedef struct __fehbutton fehbutton;
+typedef struct __fehbb fehbb;
 
 #endif