mirror of
https://github.com/labwc/labwc.git
synced 2026-03-12 05:33:53 -04:00
mousebind: add support for more contexts and mouse events
This commit is contained in:
parent
98085b4546
commit
6b948c7106
4 changed files with 89 additions and 30 deletions
|
|
@ -7,6 +7,9 @@
|
||||||
enum mouse_event {
|
enum mouse_event {
|
||||||
MOUSE_ACTION_NONE = 0,
|
MOUSE_ACTION_NONE = 0,
|
||||||
MOUSE_ACTION_DOUBLECLICK,
|
MOUSE_ACTION_DOUBLECLICK,
|
||||||
|
MOUSE_ACTION_CLICK,
|
||||||
|
MOUSE_ACTION_PRESS,
|
||||||
|
MOUSE_ACTION_RELEASE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mousebind {
|
struct mousebind {
|
||||||
|
|
@ -21,6 +24,7 @@ struct mousebind {
|
||||||
const char *command;
|
const char *command;
|
||||||
|
|
||||||
struct wl_list link; /* rcxml::mousebinds */
|
struct wl_list link; /* rcxml::mousebinds */
|
||||||
|
bool pressed_in_context; /* used in click events */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mouse_event mousebind_event_from_str(const char *str);
|
enum mouse_event mousebind_event_from_str(const char *str);
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,14 @@ enum mouse_event
|
||||||
mousebind_event_from_str(const char *str)
|
mousebind_event_from_str(const char *str)
|
||||||
{
|
{
|
||||||
assert(str);
|
assert(str);
|
||||||
if (strcasecmp(str, "doubleclick") == 0) {
|
if (!strcasecmp(str, "doubleclick")) {
|
||||||
return MOUSE_ACTION_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);
|
wlr_log(WLR_ERROR, "unknown mouse action (%s)", str);
|
||||||
return MOUSE_ACTION_NONE;
|
return MOUSE_ACTION_NONE;
|
||||||
|
|
@ -39,6 +45,12 @@ context_from_str(const char *str)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(str, "Titlebar")) {
|
if (!strcasecmp(str, "Titlebar")) {
|
||||||
return LAB_SSD_PART_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);
|
wlr_log(WLR_ERROR, "unknown mouse context (%s)", str);
|
||||||
return LAB_SSD_NONE;
|
return LAB_SSD_NONE;
|
||||||
|
|
|
||||||
|
|
@ -466,6 +466,9 @@ static struct {
|
||||||
const char *context, *button, *event, *action, *command;
|
const char *context, *button, *event, *action, *command;
|
||||||
} mouse_combos[] = {
|
} mouse_combos[] = {
|
||||||
{ "TitleBar", "Left", "DoubleClick", "ToggleMaximize", NULL },
|
{ "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 },
|
{ NULL, NULL, NULL, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
98
src/cursor.c
98
src/cursor.c
|
|
@ -420,6 +420,27 @@ handle_cursor_button_with_meta_key(struct view *view, uint32_t button,
|
||||||
interactive_begin(view, LAB_INPUT_STATE_RESIZE, edges);
|
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
|
static bool
|
||||||
is_double_click(long double_click_speed)
|
is_double_click(long double_click_speed)
|
||||||
{
|
{
|
||||||
|
|
@ -433,6 +454,37 @@ is_double_click(long double_click_speed)
|
||||||
return ms < double_click_speed && ms >= 0;
|
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
|
void
|
||||||
cursor_button(struct wl_listener *listener, void *data)
|
cursor_button(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -471,10 +523,13 @@ cursor_button(struct wl_listener *listener, void *data)
|
||||||
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Exit interactive move/resize/menu mode. */
|
|
||||||
server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
|
|
||||||
damage_all_outputs(server);
|
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) {
|
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
||||||
|
|
@ -507,39 +562,24 @@ cursor_button(struct wl_listener *listener, void *data)
|
||||||
desktop_raise_view(view);
|
desktop_raise_view(view);
|
||||||
damage_all_outputs(server);
|
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);
|
resize_edges = ssd_resize_edges(view_area);
|
||||||
if (resize_edges) {
|
if (resize_edges) {
|
||||||
interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges);
|
interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (view_area) {
|
mousebindings:
|
||||||
case LAB_SSD_BUTTON_CLOSE:
|
if (event->state == WLR_BUTTON_RELEASED) {
|
||||||
view->impl->close(view);
|
handle_release_mousebinding(server, event->button, view_area);
|
||||||
break;
|
return;
|
||||||
case LAB_SSD_BUTTON_ICONIFY:
|
} else if (event->state == WLR_BUTTON_PRESSED) {
|
||||||
view_minimize(view, true);
|
if (handle_press_mousebinding(server, event->button, view_area)) {
|
||||||
break;
|
return;
|
||||||
case LAB_SSD_PART_TITLEBAR:
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (view_area == LAB_SSD_PART_TITLEBAR) {
|
||||||
interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
|
interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
|
||||||
break;
|
|
||||||
case LAB_SSD_BUTTON_MAXIMIZE:
|
|
||||||
view_toggle_maximize(view);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue