mousebind_event_from_str(const char *str)
{
assert(str);
- if (strcasecmp(str, "doubleclick") == 0) {
+ if (!strcasecmp(str, "doubleclick")) {
return MOUSE_ACTION_DOUBLECLICK;
+ } else if (!strcasecmp(str, "click")) {
+ return MOUSE_ACTION_CLICK;
+ } else if (!strcasecmp(str, "press")) {
+ return MOUSE_ACTION_PRESS;
+ } else if (!strcasecmp(str, "release")) {
+ return MOUSE_ACTION_RELEASE;
}
wlr_log(WLR_ERROR, "unknown mouse action (%s)", str);
return MOUSE_ACTION_NONE;
{
if (!strcasecmp(str, "Titlebar")) {
return LAB_SSD_PART_TITLEBAR;
+ } else if (!strcasecmp(str, "Close")) {
+ return LAB_SSD_BUTTON_CLOSE;
+ } else if (!strcasecmp(str, "Maximize")) {
+ return LAB_SSD_BUTTON_MAXIMIZE;
+ } else if (!strcasecmp(str, "Iconify")) {
+ return LAB_SSD_BUTTON_ICONIFY;
}
wlr_log(WLR_ERROR, "unknown mouse context (%s)", str);
return LAB_SSD_NONE;
const char *context, *button, *event, *action, *command;
} mouse_combos[] = {
{ "TitleBar", "Left", "DoubleClick", "ToggleMaximize", NULL },
+ { "Close", "Left", "Click", "Close", NULL },
+ { "Iconify", "Left", "Click", "Iconify", NULL},
+ { "Maximize", "Left", "Click", "ToggleMaximize", NULL},
{ NULL, NULL, NULL, NULL, NULL },
};
interactive_begin(view, LAB_INPUT_STATE_RESIZE, edges);
}
+static void
+handle_release_mousebinding(struct server *server, uint32_t button, enum ssd_part_type view_area)
+{
+ struct mousebind *mousebind;
+ wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) {
+ if (mousebind->context == view_area
+ && mousebind->button == button) {
+ if (mousebind->mouse_event
+ == MOUSE_ACTION_RELEASE) {
+ action(server, mousebind->action,
+ mousebind->command);
+ }
+ if (mousebind->pressed_in_context) {
+ mousebind->pressed_in_context = false;
+ action(server, mousebind->action,
+ mousebind->command);
+ }
+ }
+ }
+}
+
static bool
is_double_click(long double_click_speed)
{
return ms < double_click_speed && ms >= 0;
}
+static bool
+handle_press_mousebinding(struct server *server, uint32_t button, enum ssd_part_type view_area)
+{
+ struct mousebind *mousebind;
+ bool double_click = is_double_click(rc.doubleclick_time);
+ bool bound;
+
+ wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) {
+ if (mousebind->context == view_area
+ && mousebind->button == button) {
+ if (mousebind->mouse_event
+ == MOUSE_ACTION_PRESS) {
+ bound = true;
+ action(server, mousebind->action,
+ mousebind->command);
+ } else if (mousebind->mouse_event
+ == MOUSE_ACTION_CLICK) {
+ bound = true;
+ mousebind->pressed_in_context = true;
+ } else if (double_click
+ && mousebind->mouse_event
+ == MOUSE_ACTION_DOUBLECLICK) {
+ bound = true;
+ action(server, mousebind->action,
+ mousebind->command);
+ }
+ }
+ }
+ return bound;
+}
+
void
cursor_button(struct wl_listener *listener, void *data)
{
if (server->input_mode == LAB_INPUT_STATE_MENU) {
return;
}
- /* Exit interactive move/resize/menu mode. */
- server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
damage_all_outputs(server);
- return;
+ if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
+ /* Exit interactive move/resize/menu mode. */
+ server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
+ return;
+ }
+ goto mousebindings;
}
if (server->input_mode == LAB_INPUT_STATE_MENU) {
desktop_raise_view(view);
damage_all_outputs(server);
- if (is_double_click(rc.doubleclick_time)
- && view_area == LAB_SSD_PART_TITLEBAR) {
- struct mousebind *mousebind;
- wl_list_for_each_reverse (mousebind, &rc.mousebinds, link) {
- /* TODO: make this more generic */
- if ((mousebind->context == LAB_SSD_PART_TITLEBAR) &&
- (mousebind->mouse_event == MOUSE_ACTION_DOUBLECLICK) &&
- (mousebind->button == event->button)) {
- action(server, mousebind->action, mousebind->command);
- }
- }
- return;
- }
-
resize_edges = ssd_resize_edges(view_area);
if (resize_edges) {
interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges);
return;
}
- switch (view_area) {
- case LAB_SSD_BUTTON_CLOSE:
- view->impl->close(view);
- break;
- case LAB_SSD_BUTTON_ICONIFY:
- view_minimize(view, true);
- break;
- case LAB_SSD_PART_TITLEBAR:
+mousebindings:
+ if (event->state == WLR_BUTTON_RELEASED) {
+ handle_release_mousebinding(server, event->button, view_area);
+ return;
+ } else if (event->state == WLR_BUTTON_PRESSED) {
+ if (handle_press_mousebinding(server, event->button, view_area)) {
+ return;
+ }
+ }
+
+ if (view_area == LAB_SSD_PART_TITLEBAR) {
interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
- break;
- case LAB_SSD_BUTTON_MAXIMIZE:
- view_toggle_maximize(view);
- break;
}
}