wlr_cursor_attach_output_layout(server.cursor, server.output_layout);
// This is done below
- //server.cursor_mgr = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE);
- //if (!server.cursor_mgr) {
+ // server.cursor_mgr = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE);
+ // if (!server.cursor_mgr) {
// wlr_log(WLR_ERROR, "cannot create xcursor manager");
// return 1;
//}
wl_list_remove(&_output->link);
free(_output);
}
- struct output *_keyboard, *_keyboard_tmp;
- wl_list_for_each_safe (_keyboard, _keyboard_tmp, &server.keyboards, link) {
- wl_list_remove(&_keyboard->link);
- free(_keyboard);
+ struct output *k, *k_tmp;
+ wl_list_for_each_safe (k, k_tmp, &server.keyboards, link) {
+ wl_list_remove(&k->link);
+ free(k);
}
wlr_cursor_destroy(server.cursor);
wlr_output_layout_destroy(server.output_layout);
struct timespec *when;
};
+static void render_grab(struct output *output)
+{
+ if (output->server->cursor_mode == TINYWL_CURSOR_PASSTHROUGH)
+ return;
+
+ if (output->server->cursor_mode == TINYWL_CURSOR_RESIZE) {
+ float grab_box_color[] = { 0.0, 1.0, 0.0, 0.3 };
+ wlr_render_rect(output->server->renderer,
+ &output->server->grab_box, grab_box_color,
+ output->wlr_output->transform_matrix);
+ }
+
+ float grab_point_color[] = { 1.0, 0.0, 1.0, 1.0 };
+ struct wlr_box point = { .x = output->server->grab_x +
+ output->server->grabbed_view->x - 1,
+ .y = output->server->grab_y +
+ output->server->grabbed_view->y - 1,
+ .width = 3,
+ .height = 3 };
+ fprintf(stderr, "XX grab_x=%f; grab_y=%f\n", output->server->grab_x,
+ output->server->grab_y);
+ wlr_render_rect(output->server->renderer, &point, grab_point_color,
+ output->wlr_output->transform_matrix);
+}
+
+static void render_cycle_box(struct output *output)
+{
+ if (!output->server->cycle_view)
+ return;
+ struct view *view;
+ wl_list_for_each_reverse (view, &output->server->views, link) {
+ if (view != output->server->cycle_view)
+ continue;
+ struct wlr_box box = deco_max_extents(view);
+ float cycle_color[] = { 0.0, 0.0, 0.0, 0.2 };
+ wlr_render_rect(output->server->renderer, &box, cycle_color,
+ output->wlr_output->transform_matrix);
+ return;
+ }
+}
+
static void render_decorations(struct wlr_output *output, struct view *view)
{
if (!view_want_deco(view))
}
}
+ /* If in cycle (alt-tab) mode, highlight selected view */
+ render_cycle_box(output);
+ render_grab(output);
+
/* Hardware cursors are rendered by the GPU on a separate plane, and can
* be moved around without re-rendering what's beneath them - which is
* more efficient. However, not all hardware supports hardware cursors.
#include "labwc.h"
-static bool in_alt_tab_mode;
-static struct view *alt_tab_view;
+static struct wlr_box view_geometry(struct view *view)
+{
+ struct wlr_box box = { 0 };
+ switch (view->type) {
+ case LAB_XDG_SHELL_VIEW:
+ wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
+ break;
+ case LAB_XWAYLAND_VIEW:
+ box.width = view->xwayland_surface->width;
+ box.height = view->xwayland_surface->height;
+ break;
+ }
+ return box;
+}
-void begin_interactive(struct view *view, enum cursor_mode mode,
- uint32_t edges)
+void begin_interactive(struct view *view, enum cursor_mode mode, uint32_t edges)
{
/* This function sets up an interactive move or resize operation, where
* the compositor stops propegating pointer events to clients and
server->grabbed_view = view;
server->cursor_mode = mode;
- if (mode == TINYWL_CURSOR_MOVE) {
+ switch (mode) {
+ case TINYWL_CURSOR_MOVE:
server->grab_x = server->cursor->x - view->x;
server->grab_y = server->cursor->y - view->y;
- } else {
- struct wlr_box geo_box;
- switch (view->type) {
- case LAB_XDG_SHELL_VIEW:
- wlr_xdg_surface_get_geometry(view->xdg_surface,
- &geo_box);
- break;
- case LAB_XWAYLAND_VIEW:
- geo_box.x = view->xwayland_surface->x;
- geo_box.y = view->xwayland_surface->y;
- geo_box.width = view->xwayland_surface->width;
- geo_box.height = view->xwayland_surface->height;
- break;
- }
-
+ break;
+ case TINYWL_CURSOR_RESIZE: {
+ struct wlr_box geo_box = view_geometry(view);
double border_x =
(view->x + geo_box.x) +
((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0);
server->grab_box.x += view->x;
server->grab_box.y += view->y;
server->resize_edges = edges;
+ } break;
+ default:
+ break;
}
}
break;
case XKB_KEY_F1:
case XKB_KEY_F2:
- in_alt_tab_mode = true;
- alt_tab_view = next_toplevel(view_front_toplevel(server));
- fprintf(stderr, "alt_tab_view=%p\n", (void *)alt_tab_view);
+ server->cycle_view = next_toplevel(view_front_toplevel(server));
+ fprintf(stderr, "cycle_view=%p\n", (void *)server->cycle_view);
break;
case XKB_KEY_F3:
if (fork() == 0) {
uint32_t modifiers =
wlr_keyboard_get_modifiers(keyboard->device->keyboard);
- if (in_alt_tab_mode) {
+ if (server->cycle_view) {
if ((syms[0] == XKB_KEY_Alt_L) &&
event->state == WLR_KEY_RELEASED) {
/* end cycle */
- in_alt_tab_mode = false;
- view_focus(alt_tab_view);
+ view_focus(server->cycle_view);
+ server->cycle_view = NULL;
} else if (event->state == WLR_KEY_PRESSED) {
/* cycle to next */
- alt_tab_view = next_toplevel(alt_tab_view);
- fprintf(stderr, "alt_tab_view=%p\n",
- (void *)alt_tab_view);
+ server->cycle_view = next_toplevel(server->cycle_view);
+ fprintf(stderr, "cycle_view=%p\n",
+ (void *)server->cycle_view);
return;
}
}
static void process_cursor_resize(struct server *server, uint32_t time)
{
/*
- * Resizing the grabbed view can be a little bit complicated, because we
- * could be resizing from any corner or edge. This not only resizes the
- * view on one or two axes, but can also move the view if you resize
- * from the top or left edges (or top-left corner).
- *
* TODO: Wait for the client to prepare a buffer at the new size, then
* commit any movement that was prepared.
*/
new_right = new_left + 1;
}
- struct wlr_box geo_box;
- wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
+ struct wlr_box geo_box = view_geometry(view);
view->x = new_left - geo_box.x;
view->y = new_top - geo_box.y;
int new_width = new_right - new_left;
int new_height = new_bottom - new_top;
- wlr_xdg_toplevel_set_size(view->xdg_surface, new_width, new_height);
+ switch (view->type) {
+ case LAB_XDG_SHELL_VIEW:
+ wlr_xdg_toplevel_set_size(view->xdg_surface, new_width,
+ new_height);
+ break;
+ case LAB_XWAYLAND_VIEW:
+ wlr_xwayland_surface_configure(view->xwayland_surface, view->x,
+ view->y, new_width, new_height);
+ break;
+ }
}
static void process_cursor_motion(struct server *server, uint32_t time)
wlr_xcursor_manager_set_cursor_image(
server->cursor_mgr, "left_ptr", server->cursor);
break;
+ case LAB_DECO_PART_LEFT:
+ wlr_xcursor_manager_set_cursor_image(
+ server->cursor_mgr, "left_side", server->cursor);
+ break;
}
if (surface) {
bool focus_changed = seat->pointer_state.focused_surface !=
case LAB_DECO_PART_TOP:
begin_interactive(view, TINYWL_CURSOR_MOVE, 0);
break;
+ case LAB_DECO_PART_LEFT:
+ begin_interactive(view, TINYWL_CURSOR_RESIZE,
+ WLR_EDGE_LEFT);
+ break;
}
}
}