1
0
mirror of https://codeberg.org/vyivel/dulcepan/ synced 2025-03-12 10:49:15 +02:00

seat: allow toggling whole output selection

Closes: https://codeberg.org/vyivel/dulcepan/issues/20
This commit is contained in:
Kirill Primak 2025-01-30 23:11:07 +03:00
parent 9879f3ad69
commit 0167c017a0
4 changed files with 61 additions and 11 deletions

View File

@ -126,6 +126,14 @@ struct dp_selection {
int resize_edges;
// Resize anchor
double resize_x, resize_y;
// Used for toggling
struct {
// If not NULL, the current output has been selected via the dedicated
// action rather than by persistent state loading or manual resizing
struct dp_output *output;
double x, y, width, height;
} last_partial;
};
enum dp_file_format {
@ -232,7 +240,7 @@ void dp_select_stop_interactive(struct dp_selection *selection);
void dp_select_notify_pointer_position(
struct dp_selection *selection, struct dp_output *output, double x, double y);
void dp_select_whole(struct dp_selection *selection, struct dp_output *output);
void dp_select_toggle_whole(struct dp_selection *selection, struct dp_output *output);
void dp_save(struct dp_state *state);

View File

@ -176,7 +176,7 @@ static void help(const char *prog) {
"\n"
"Use the left or right mouse button to select a part of the output. A selection\n"
"can also be moved and resized with the left mouse button. Clicking the middle\n"
"mouse button selects the entire output.\n",
"mouse button toggles the selection of the entire output.\n",
prog);
}

View File

@ -201,9 +201,9 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uin
update_cursor(seat);
break;
case BTN_MIDDLE:
dp_select_whole(selection, seat->ptr_output);
dp_select_toggle_whole(selection, seat->ptr_output);
// dp_select_whole() doesn't invalidate the interactive state, so do it manually
// Update the interaction state manually
dp_select_notify_pointer_position(selection, seat->ptr_output, seat->ptr_x, seat->ptr_y);
update_cursor(seat);

View File

@ -20,6 +20,24 @@ static void set_selected_output(struct dp_selection *selection, struct dp_output
}
}
static inline bool has_last_partial(struct dp_selection *selection) {
return selection->last_partial.output != NULL;
}
static inline void reset_last_partial(struct dp_selection *selection) {
selection->last_partial.output = NULL;
}
static bool has_partial(struct dp_selection *selection) {
struct dp_output *output = selection->output;
if (output == NULL) {
return false;
}
return selection->x != 0 || selection->y != 0 || selection->width != output->effective_width ||
selection->height != output->effective_height;
}
static void update_action(
struct dp_selection *selection, struct dp_output *output, double x, double y) {
if (output == selection->output) {
@ -161,6 +179,8 @@ void dp_select_start_interactive(struct dp_selection *selection, struct dp_outpu
update_action(selection, output, x, y);
selection->action_active = true;
reset_last_partial(selection);
if (modify_existing) {
switch (selection->action) {
case DP_SELECTION_ACTION_NONE:
@ -213,13 +233,35 @@ void dp_select_notify_pointer_position(
}
}
void dp_select_whole(struct dp_selection *selection, struct dp_output *output) {
set_selected_output(selection, output);
void dp_select_toggle_whole(struct dp_selection *selection, struct dp_output *output) {
if (selection->output == output && has_last_partial(selection)) {
// Toggle the selection back to the last partial one
set_selected_output(selection, selection->last_partial.output);
selection->x = 0;
selection->y = 0;
selection->width = output->effective_width;
selection->height = output->effective_height;
selection->x = selection->last_partial.x;
selection->y = selection->last_partial.y;
selection->width = selection->last_partial.width;
selection->height = selection->last_partial.height;
dp_output_redraw(output);
reset_last_partial(selection);
} else {
// Don't save another whole output selection as partial
if (has_partial(selection) && !has_last_partial(selection)) {
selection->last_partial.output = selection->output;
selection->last_partial.x = selection->x;
selection->last_partial.y = selection->y;
selection->last_partial.width = selection->width;
selection->last_partial.height = selection->height;
}
set_selected_output(selection, output);
selection->x = 0;
selection->y = 0;
selection->width = output->effective_width;
selection->height = output->effective_height;
}
dp_output_redraw(selection->output);
}