commit 08b22df90da20cf7f81bf98f434d9128d7cfd418
parent ee64b7ee612b2edaf45339421eef478cd2f38dac
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 24 Apr 2019 21:58:27 -0400
Implement basic menu interactions with mouse
Diffstat:
4 files changed, 51 insertions(+), 16 deletions(-)
diff --git a/include/server.h b/include/server.h
@@ -41,6 +41,7 @@ struct wio_server {
struct {
int x, y;
+ int width, height;
struct wlr_texture *active_textures[5];
struct wlr_texture *inactive_textures[5];
} menu;
diff --git a/input.c b/input.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <linux/input-event-codes.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_input_device.h>
@@ -97,6 +98,36 @@ void server_cursor_motion_absolute(
process_cursor_motion(server, event->time_msec);
}
+static void handle_button_internal(
+ struct wio_server *server, struct wlr_event_pointer_button *event) {
+ // TODO: open menu if the client doesn't handle the button press
+ // will basically involve some serial hacking
+ struct wlr_box menu_box = {
+ .x = server->menu.x, .y = server->menu.y,
+ .width = server->menu.width, .height = server->menu.height,
+ };
+ if (server->menu.x != -1 && server->menu.y != -1) {
+ if (wlr_box_contains_point(
+ &menu_box, server->cursor->x, server->cursor->y)) {
+ // TODO: menu_handle_button()
+ } else {
+ if (event->state == WLR_BUTTON_PRESSED) {
+ server->menu.x = server->menu.y = -1;
+ }
+ }
+ } else {
+ if (event->state == WLR_BUTTON_PRESSED) {
+ switch (event->button) {
+ case BTN_RIGHT:
+ // TODO: Open over the last-used menu item
+ server->menu.x = server->cursor->x;
+ server->menu.y = server->cursor->y;
+ break;
+ }
+ }
+ }
+}
+
void server_cursor_button(struct wl_listener *listener, void *data) {
struct wio_server *server =
wl_container_of(listener, server, cursor_button);
@@ -108,6 +139,8 @@ void server_cursor_button(struct wl_listener *listener, void *data) {
server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
if (view) {
wio_view_focus(view, surface);
+ } else {
+ handle_button_internal(server, event);
}
wlr_seat_pointer_notify_button(server->seat,
event->time_msec, event->button, event->state);
diff --git a/main.c b/main.c
@@ -116,7 +116,7 @@ int main(int argc, char **argv) {
wl_signal_add(&server.xdg_shell->events.new_surface,
&server.new_xdg_surface);
- server.menu.x = server.menu.y = 10;
+ server.menu.x = server.menu.y = -1;
gen_menu_textures(&server);
const char *socket = wl_display_add_socket_auto(server.wl_display);
diff --git a/output.c b/output.c
@@ -101,33 +101,34 @@ static void render_menu(struct wio_output *output) {
oy += margin;
for (size_t i = 0; i < ntextures; ++i) {
int width, height;
- struct wlr_texture *texture;
- if (i == 0) { // TODO: if cursor is over this menu item
+ struct wlr_texture *texture = server->menu.inactive_textures[i];
+ wlr_texture_get_size(texture, &width, &height);
+ struct wlr_box box = { 0 };
+ box.x = ox - 1 * scale;
+ box.y = oy - 1 * scale;
+ box.width = (text_width - border) * scale;
+ box.height = (height + margin) * scale;
+ if (wlr_box_contains_point(
+ &box, server->cursor->x, server->cursor->y)) {
texture = server->menu.active_textures[i];
- wlr_texture_get_size(texture, &width, &height);
- struct wlr_box box = {
- .x = ox - 1 * scale, .y = oy - 1 * scale,
- .width = (text_width - border) * scale,
- .height = (height + margin) * scale,
- };
wlr_render_rect(renderer, &box, menu_selected,
output->wlr_output->transform_matrix);
} else {
- texture = server->menu.inactive_textures[i];
wlr_texture_get_size(texture, &width, &height);
}
- struct wlr_box box = {
- .x = (ox + (text_width / 2 - width / 2)) * scale,
- .y = oy * scale,
- .width = width * scale,
- .height = height * scale,
- };
+ box.x = (ox + (text_width / 2 - width / 2)) * scale;
+ box.y = oy * scale;
+ box.width = width * scale;
+ box.height = height * scale;
float matrix[9];
wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
output->wlr_output->transform_matrix);
wlr_render_texture_with_matrix(renderer, texture, matrix, 1);
oy += height + margin;
}
+
+ server->menu.width = text_width;
+ server->menu.height = text_height;
}
static void output_frame(struct wl_listener *listener, void *data) {