1
0
mirror of https://codeberg.org/vyivel/dulcepan/ synced 2025-12-17 07:35:13 +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; int resize_edges;
// Resize anchor // Resize anchor
double resize_x, resize_y; 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 { enum dp_file_format {
@@ -232,7 +240,7 @@ void dp_select_stop_interactive(struct dp_selection *selection);
void dp_select_notify_pointer_position( void dp_select_notify_pointer_position(
struct dp_selection *selection, struct dp_output *output, double x, double y); 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); void dp_save(struct dp_state *state);

View File

@@ -176,7 +176,7 @@ static void help(const char *prog) {
"\n" "\n"
"Use the left or right mouse button to select a part of the output. A selection\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" "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); prog);
} }

View File

@@ -201,9 +201,9 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uin
update_cursor(seat); update_cursor(seat);
break; break;
case BTN_MIDDLE: 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); dp_select_notify_pointer_position(selection, seat->ptr_output, seat->ptr_x, seat->ptr_y);
update_cursor(seat); 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( static void update_action(
struct dp_selection *selection, struct dp_output *output, double x, double y) { struct dp_selection *selection, struct dp_output *output, double x, double y) {
if (output == selection->output) { 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); update_action(selection, output, x, y);
selection->action_active = true; selection->action_active = true;
reset_last_partial(selection);
if (modify_existing) { if (modify_existing) {
switch (selection->action) { switch (selection->action) {
case DP_SELECTION_ACTION_NONE: 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) { 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 = selection->last_partial.x;
selection->y = selection->last_partial.y;
selection->width = selection->last_partial.width;
selection->height = selection->last_partial.height;
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); set_selected_output(selection, output);
selection->x = 0; selection->x = 0;
selection->y = 0; selection->y = 0;
selection->width = output->effective_width; selection->width = output->effective_width;
selection->height = output->effective_height; selection->height = output->effective_height;
}
dp_output_redraw(output);
dp_output_redraw(selection->output);
} }