mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-12 05:34:01 -04:00
Merge branch 'visual-focus'
This commit is contained in:
commit
43b76f002f
7 changed files with 173 additions and 67 deletions
40
input.c
40
input.c
|
|
@ -87,11 +87,11 @@ keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
|
|
||||||
struct wayland *wayl = data;
|
struct wayland *wayl = data;
|
||||||
wayl->input_serial = serial;
|
wayl->input_serial = serial;
|
||||||
wayl->focused = wayl_terminal_from_surface(wayl, surface);
|
wayl->kbd_focus = wayl_terminal_from_surface(wayl, surface);
|
||||||
assert(wayl->focused != NULL);
|
assert(wayl->kbd_focus != NULL);
|
||||||
|
|
||||||
term_focus_in(wayl->focused);
|
term_kbd_focus_in(wayl->kbd_focus);
|
||||||
term_xcursor_update(wayl->focused);
|
term_xcursor_update(wayl->kbd_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -143,23 +143,23 @@ keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
struct wayland *wayl = data;
|
struct wayland *wayl = data;
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
wayl->focused == NULL ||
|
wayl->kbd_focus == NULL ||
|
||||||
surface == NULL || /* Seen on Sway 1.2 */
|
surface == NULL || /* Seen on Sway 1.2 */
|
||||||
wayl_terminal_from_surface(wayl, surface) == wayl->focused);
|
wayl_terminal_from_surface(wayl, surface) == wayl->kbd_focus);
|
||||||
|
|
||||||
struct terminal *old_focused = wayl->focused;
|
struct terminal *old_focused = wayl->kbd_focus;
|
||||||
wayl->focused = NULL;
|
wayl->kbd_focus = NULL;
|
||||||
|
|
||||||
stop_repeater(wayl, -1);
|
stop_repeater(wayl, -1);
|
||||||
if (old_focused != NULL) {
|
if (old_focused != NULL) {
|
||||||
|
term_kbd_focus_out(old_focused);
|
||||||
|
term_xcursor_update(old_focused);
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* Sway bug - under certain conditions we get a
|
* Sway bug - under certain conditions we get a
|
||||||
* keyboard_leave() (and keyboard_key()) without first having
|
* keyboard_leave() (and keyboard_key()) without first having
|
||||||
* received a keyboard_enter()
|
* received a keyboard_enter()
|
||||||
*/
|
*/
|
||||||
term_focus_out(old_focused);
|
|
||||||
term_xcursor_update(old_focused);
|
|
||||||
} else {
|
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"compositor sent keyboard_leave event without a keyboard_enter "
|
"compositor sent keyboard_leave event without a keyboard_enter "
|
||||||
"event: surface=%p", surface);
|
"event: surface=%p", surface);
|
||||||
|
|
@ -171,7 +171,7 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
uint32_t time, uint32_t key, uint32_t state)
|
uint32_t time, uint32_t key, uint32_t state)
|
||||||
{
|
{
|
||||||
struct wayland *wayl = data;
|
struct wayland *wayl = data;
|
||||||
struct terminal *term = wayl->focused;
|
struct terminal *term = wayl->kbd_focus;
|
||||||
|
|
||||||
/* Workaround buggy Sway 1.2 */
|
/* Workaround buggy Sway 1.2 */
|
||||||
if (term == NULL) {
|
if (term == NULL) {
|
||||||
|
|
@ -409,8 +409,8 @@ keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
wayl->kbd.meta = xkb_state_mod_index_is_active(
|
wayl->kbd.meta = xkb_state_mod_index_is_active(
|
||||||
wayl->kbd.xkb_state, wayl->kbd.mod_meta, XKB_STATE_MODS_DEPRESSED);
|
wayl->kbd.xkb_state, wayl->kbd.mod_meta, XKB_STATE_MODS_DEPRESSED);
|
||||||
|
|
||||||
if (wayl->focused)
|
if (wayl->kbd_focus)
|
||||||
term_xcursor_update(wayl->focused);
|
term_xcursor_update(wayl->kbd_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -450,7 +450,7 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
|
||||||
LOG_DBG("pointer-enter: surface = %p, new-moused = %p", surface, term);
|
LOG_DBG("pointer-enter: surface = %p, new-moused = %p", surface, term);
|
||||||
|
|
||||||
wayl->moused = term;
|
wayl->mouse_focus = term;
|
||||||
|
|
||||||
int x = wl_fixed_to_int(surface_x) * term->scale;
|
int x = wl_fixed_to_int(surface_x) * term->scale;
|
||||||
int y = wl_fixed_to_int(surface_y) * term->scale;
|
int y = wl_fixed_to_int(surface_y) * term->scale;
|
||||||
|
|
@ -466,11 +466,11 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,
|
||||||
uint32_t serial, struct wl_surface *surface)
|
uint32_t serial, struct wl_surface *surface)
|
||||||
{
|
{
|
||||||
struct wayland *wayl = data;
|
struct wayland *wayl = data;
|
||||||
struct terminal *old_moused = wayl->moused;
|
struct terminal *old_moused = wayl->mouse_focus;
|
||||||
|
|
||||||
LOG_DBG("pointer-leave: surface = %p, old-moused = %p", surface, old_moused);
|
LOG_DBG("pointer-leave: surface = %p, old-moused = %p", surface, old_moused);
|
||||||
|
|
||||||
wayl->moused = NULL;
|
wayl->mouse_focus = NULL;
|
||||||
if (old_moused == NULL) {
|
if (old_moused == NULL) {
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"compositor sent pointer_leave event without a pointer_enter "
|
"compositor sent pointer_leave event without a pointer_enter "
|
||||||
|
|
@ -484,7 +484,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
||||||
uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||||
{
|
{
|
||||||
struct wayland *wayl = data;
|
struct wayland *wayl = data;
|
||||||
struct terminal *term = wayl->moused;
|
struct terminal *term = wayl->mouse_focus;
|
||||||
|
|
||||||
/* Workaround buggy Sway 1.2 */
|
/* Workaround buggy Sway 1.2 */
|
||||||
if (term == NULL) {
|
if (term == NULL) {
|
||||||
|
|
@ -540,7 +540,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
LOG_DBG("BUTTON: button=%x, state=%u", button, state);
|
LOG_DBG("BUTTON: button=%x, state=%u", button, state);
|
||||||
|
|
||||||
struct wayland *wayl = data;
|
struct wayland *wayl = data;
|
||||||
struct terminal *term = wayl->moused;
|
struct terminal *term = wayl->mouse_focus;
|
||||||
|
|
||||||
/* Workaround buggy Sway 1.2 */
|
/* Workaround buggy Sway 1.2 */
|
||||||
if (term == NULL) {
|
if (term == NULL) {
|
||||||
|
|
@ -621,7 +621,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
static void
|
static void
|
||||||
mouse_scroll(struct wayland *wayl, int amount)
|
mouse_scroll(struct wayland *wayl, int amount)
|
||||||
{
|
{
|
||||||
struct terminal *term = wayl->moused;
|
struct terminal *term = wayl->mouse_focus;
|
||||||
assert(term != NULL);
|
assert(term != NULL);
|
||||||
|
|
||||||
int button = amount < 0 ? BTN_BACK : BTN_FORWARD;
|
int button = amount < 0 ? BTN_BACK : BTN_FORWARD;
|
||||||
|
|
|
||||||
13
render.c
13
render.c
|
|
@ -279,8 +279,6 @@ draw_cursor(const struct terminal *term, const struct cell *cell,
|
||||||
pixman_image_t *pix, pixman_color_t *fg, const pixman_color_t *bg,
|
pixman_image_t *pix, pixman_color_t *fg, const pixman_color_t *bg,
|
||||||
int x, int y, int cols)
|
int x, int y, int cols)
|
||||||
{
|
{
|
||||||
bool have_focus = term->wl->focused == term;
|
|
||||||
|
|
||||||
pixman_color_t cursor_color;
|
pixman_color_t cursor_color;
|
||||||
pixman_color_t text_color;
|
pixman_color_t text_color;
|
||||||
|
|
||||||
|
|
@ -307,7 +305,7 @@ draw_cursor(const struct terminal *term, const struct cell *cell,
|
||||||
|
|
||||||
switch (term->cursor_style) {
|
switch (term->cursor_style) {
|
||||||
case CURSOR_BLOCK:
|
case CURSOR_BLOCK:
|
||||||
if (!have_focus)
|
if (!term->visual_focus)
|
||||||
draw_unfocused_block(term, pix, &cursor_color, x, y, cols);
|
draw_unfocused_block(term, pix, &cursor_color, x, y, cols);
|
||||||
|
|
||||||
else if (term->cursor_blink.state == CURSOR_BLINK_ON) {
|
else if (term->cursor_blink.state == CURSOR_BLINK_ON) {
|
||||||
|
|
@ -319,12 +317,12 @@ draw_cursor(const struct terminal *term, const struct cell *cell,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURSOR_BAR:
|
case CURSOR_BAR:
|
||||||
if (term->cursor_blink.state == CURSOR_BLINK_ON || !have_focus)
|
if (term->cursor_blink.state == CURSOR_BLINK_ON || !term->visual_focus)
|
||||||
draw_bar(term, pix, font, &cursor_color, x, y);
|
draw_bar(term, pix, font, &cursor_color, x, y);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURSOR_UNDERLINE:
|
case CURSOR_UNDERLINE:
|
||||||
if (term->cursor_blink.state == CURSOR_BLINK_ON || !have_focus) {
|
if (term->cursor_blink.state == CURSOR_BLINK_ON || !term->visual_focus) {
|
||||||
draw_underline(
|
draw_underline(
|
||||||
term, pix, attrs_to_font(term, &cell->attrs), &cursor_color,
|
term, pix, attrs_to_font(term, &cell->attrs), &cursor_color,
|
||||||
x, y, cols);
|
x, y, cols);
|
||||||
|
|
@ -962,7 +960,7 @@ reflow(struct row **new_grid, int new_cols, int new_rows,
|
||||||
|
|
||||||
/* Move to terminal.c? */
|
/* Move to terminal.c? */
|
||||||
void
|
void
|
||||||
render_resize(struct terminal *term, int width, int height)
|
render_resize(struct terminal *term, int width, int height, bool refresh)
|
||||||
{
|
{
|
||||||
int scale = -1;
|
int scale = -1;
|
||||||
tll_foreach(term->window->on_outputs, it) {
|
tll_foreach(term->window->on_outputs, it) {
|
||||||
|
|
@ -1085,7 +1083,8 @@ render_resize(struct terminal *term, int width, int height)
|
||||||
term->render.last_cursor.cell = NULL;
|
term->render.last_cursor.cell = NULL;
|
||||||
|
|
||||||
term_damage_view(term);
|
term_damage_view(term);
|
||||||
render_refresh(term);
|
if (refresh)
|
||||||
|
render_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
2
render.h
2
render.h
|
|
@ -6,7 +6,7 @@ struct font *attrs_to_font(
|
||||||
const struct terminal *term, const struct attributes *attrs);
|
const struct terminal *term, const struct attributes *attrs);
|
||||||
|
|
||||||
void grid_render(struct terminal *term);
|
void grid_render(struct terminal *term);
|
||||||
void render_resize(struct terminal *term, int width, int height);
|
void render_resize(struct terminal *term, int width, int height, bool refresh);
|
||||||
void render_set_title(struct terminal *term, const char *title);
|
void render_set_title(struct terminal *term, const char *title);
|
||||||
void render_refresh(struct terminal *term);
|
void render_refresh(struct terminal *term);
|
||||||
|
|
||||||
|
|
|
||||||
66
terminal.c
66
terminal.c
|
|
@ -653,10 +653,16 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
if ((term->slave = slave_spawn(term->ptmx, argc, term->cwd, argv, term_env, conf->shell)) == -1)
|
if ((term->slave = slave_spawn(term->ptmx, argc, term->cwd, argv, term_env, conf->shell)) == -1)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Initiailze the Wayland window backend */
|
/* Initialize the Wayland window backend */
|
||||||
if ((term->window = wayl_win_init(wayl)) == NULL)
|
if ((term->window = wayl_win_init(wayl)) == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
/* Let the Wayland backend know we exist */
|
||||||
|
tll_push_back(wayl->terms, term);
|
||||||
|
|
||||||
|
/* Roundtrip to ensure the wayland window have been configured */
|
||||||
|
wl_display_roundtrip(term->wl->display);
|
||||||
|
|
||||||
term_set_window_title(term, "foot");
|
term_set_window_title(term, "foot");
|
||||||
|
|
||||||
/* Try to use user-configured window dimentions */
|
/* Try to use user-configured window dimentions */
|
||||||
|
|
@ -673,9 +679,8 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
/* Don't go below a single cell */
|
/* Don't go below a single cell */
|
||||||
width = max(width, term->cell_width);
|
width = max(width, term->cell_width);
|
||||||
height = max(height, term->cell_height);
|
height = max(height, term->cell_height);
|
||||||
render_resize(term, width, height);
|
render_resize(term, width, height, true);
|
||||||
|
|
||||||
tll_push_back(wayl->terms, term);
|
|
||||||
return term;
|
return term;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
@ -716,13 +721,13 @@ fdm_shutdown(struct fdm *fdm, int fd, int events, void *data)
|
||||||
* are deferred (for example, when a screen locker is active), and
|
* are deferred (for example, when a screen locker is active), and
|
||||||
* thus we can get here without having been unmapped.
|
* thus we can get here without having been unmapped.
|
||||||
*/
|
*/
|
||||||
if (wayl->focused == term)
|
if (wayl->kbd_focus == term)
|
||||||
wayl->focused = NULL;
|
wayl->kbd_focus = NULL;
|
||||||
if (wayl->moused == term)
|
if (wayl->mouse_focus == term)
|
||||||
wayl->moused = NULL;
|
wayl->mouse_focus = NULL;
|
||||||
|
|
||||||
assert(wayl->focused != term);
|
assert(wayl->kbd_focus != term);
|
||||||
assert(wayl->moused != term);
|
assert(wayl->mouse_focus != term);
|
||||||
|
|
||||||
void (*cb)(void *, int) = term->shutdown_cb;
|
void (*cb)(void *, int) = term->shutdown_cb;
|
||||||
void *cb_data = term->shutdown_data;
|
void *cb_data = term->shutdown_data;
|
||||||
|
|
@ -1234,7 +1239,7 @@ void
|
||||||
term_cursor_blink_enable(struct terminal *term)
|
term_cursor_blink_enable(struct terminal *term)
|
||||||
{
|
{
|
||||||
term->cursor_blink.state = CURSOR_BLINK_ON;
|
term->cursor_blink.state = CURSOR_BLINK_ON;
|
||||||
term->cursor_blink.active = term->wl->focused == term
|
term->cursor_blink.active = term->wl->kbd_focus == term
|
||||||
? cursor_blink_start_timer(term) : true;
|
? cursor_blink_start_timer(term) : true;
|
||||||
cursor_refresh(term);
|
cursor_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
@ -1253,7 +1258,7 @@ term_cursor_blink_restart(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (term->cursor_blink.active) {
|
if (term->cursor_blink.active) {
|
||||||
term->cursor_blink.state = CURSOR_BLINK_ON;
|
term->cursor_blink.state = CURSOR_BLINK_ON;
|
||||||
term->cursor_blink.active = term->wl->focused == term
|
term->cursor_blink.active = term->wl->kbd_focus == term
|
||||||
? cursor_blink_start_timer(term) : true;
|
? cursor_blink_start_timer(term) : true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1392,27 +1397,42 @@ term_restore_cursor(struct terminal *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_focus_in(struct terminal *term)
|
term_visual_focus_in(struct terminal *term)
|
||||||
{
|
{
|
||||||
|
if (term->visual_focus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
term->visual_focus = true;
|
||||||
if (term->cursor_blink.active)
|
if (term->cursor_blink.active)
|
||||||
cursor_blink_start_timer(term);
|
cursor_blink_start_timer(term);
|
||||||
|
cursor_refresh(term);
|
||||||
|
}
|
||||||
|
|
||||||
if (term->focus_events)
|
void
|
||||||
term_to_slave(term, "\033[I", 3);
|
term_visual_focus_out(struct terminal *term)
|
||||||
|
{
|
||||||
|
if (!term->visual_focus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
term->visual_focus = false;
|
||||||
|
if (term->cursor_blink.active)
|
||||||
|
cursor_blink_stop_timer(term);
|
||||||
|
|
||||||
cursor_refresh(term);
|
cursor_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_focus_out(struct terminal *term)
|
term_kbd_focus_in(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (term->cursor_blink.active)
|
if (term->focus_events)
|
||||||
cursor_blink_stop_timer(term);
|
term_to_slave(term, "\033[I", 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
term_kbd_focus_out(struct terminal *term)
|
||||||
|
{
|
||||||
if (term->focus_events)
|
if (term->focus_events)
|
||||||
term_to_slave(term, "\033[O", 3);
|
term_to_slave(term, "\033[O", 3);
|
||||||
|
|
||||||
cursor_refresh(term);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -1508,7 +1528,7 @@ term_mouse_grabbed(const struct terminal *term)
|
||||||
* Mouse is grabbed by us, regardless of whether mouse tracking has been enabled or not.
|
* Mouse is grabbed by us, regardless of whether mouse tracking has been enabled or not.
|
||||||
*/
|
*/
|
||||||
return
|
return
|
||||||
term->wl->focused == term &&
|
term->wl->kbd_focus == term &&
|
||||||
term->wl->kbd.shift &&
|
term->wl->kbd.shift &&
|
||||||
!term->wl->kbd.alt && !term->wl->kbd.ctrl && !term->wl->kbd.meta;
|
!term->wl->kbd.alt && !term->wl->kbd.ctrl && !term->wl->kbd.meta;
|
||||||
}
|
}
|
||||||
|
|
@ -1529,7 +1549,7 @@ term_mouse_down(struct terminal *term, int button, int row, int col)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
bool has_focus = term->wl->focused == term;
|
bool has_focus = term->wl->kbd_focus == term;
|
||||||
bool shift = has_focus ? term->wl->kbd.shift : false;
|
bool shift = has_focus ? term->wl->kbd.shift : false;
|
||||||
bool alt = has_focus ? term->wl->kbd.alt : false;
|
bool alt = has_focus ? term->wl->kbd.alt : false;
|
||||||
bool ctrl = has_focus ? term->wl->kbd.ctrl : false;
|
bool ctrl = has_focus ? term->wl->kbd.ctrl : false;
|
||||||
|
|
@ -1573,7 +1593,7 @@ term_mouse_up(struct terminal *term, int button, int row, int col)
|
||||||
if (encoded == -1)
|
if (encoded == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool has_focus = term->wl->focused == term;
|
bool has_focus = term->wl->kbd_focus == term;
|
||||||
bool shift = has_focus ? term->wl->kbd.shift : false;
|
bool shift = has_focus ? term->wl->kbd.shift : false;
|
||||||
bool alt = has_focus ? term->wl->kbd.alt : false;
|
bool alt = has_focus ? term->wl->kbd.alt : false;
|
||||||
bool ctrl = has_focus ? term->wl->kbd.ctrl : false;
|
bool ctrl = has_focus ? term->wl->kbd.ctrl : false;
|
||||||
|
|
@ -1617,7 +1637,7 @@ term_mouse_motion(struct terminal *term, int button, int row, int col)
|
||||||
} else
|
} else
|
||||||
encoded = 3; /* "released" */
|
encoded = 3; /* "released" */
|
||||||
|
|
||||||
bool has_focus = term->wl->focused == term;
|
bool has_focus = term->wl->kbd_focus == term;
|
||||||
bool shift = has_focus ? term->wl->kbd.shift : false;
|
bool shift = has_focus ? term->wl->kbd.shift : false;
|
||||||
bool alt = has_focus ? term->wl->kbd.alt : false;
|
bool alt = has_focus ? term->wl->kbd.alt : false;
|
||||||
bool ctrl = has_focus ? term->wl->kbd.ctrl : false;
|
bool ctrl = has_focus ? term->wl->kbd.ctrl : false;
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,7 @@ struct terminal {
|
||||||
|
|
||||||
struct wayland *wl;
|
struct wayland *wl;
|
||||||
struct wl_window *window;
|
struct wl_window *window;
|
||||||
|
bool visual_focus;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int scrollback_lines;
|
int scrollback_lines;
|
||||||
|
|
@ -377,8 +378,10 @@ void term_arm_blink_timer(struct terminal *term);
|
||||||
|
|
||||||
void term_restore_cursor(struct terminal *term);
|
void term_restore_cursor(struct terminal *term);
|
||||||
|
|
||||||
void term_focus_in(struct terminal *term);
|
void term_visual_focus_in(struct terminal *term);
|
||||||
void term_focus_out(struct terminal *term);
|
void term_visual_focus_out(struct terminal *term);
|
||||||
|
void term_kbd_focus_in(struct terminal *term);
|
||||||
|
void term_kbd_focus_out(struct terminal *term);
|
||||||
void term_mouse_down(struct terminal *term, int button, int row, int col);
|
void term_mouse_down(struct terminal *term, int button, int row, int col);
|
||||||
void term_mouse_up(struct terminal *term, int button, int row, int col);
|
void term_mouse_up(struct terminal *term, int button, int row, int col);
|
||||||
void term_mouse_motion(struct terminal *term, int button, int row, int col);
|
void term_mouse_motion(struct terminal *term, int button, int row, int col);
|
||||||
|
|
|
||||||
108
wayland.c
108
wayland.c
|
|
@ -142,7 +142,9 @@ output_scale(void *data, struct wl_output *wl_output, int32_t factor)
|
||||||
|
|
||||||
tll_foreach(mon->wayl->terms, it) {
|
tll_foreach(mon->wayl->terms, it) {
|
||||||
struct terminal *term = it->item;
|
struct terminal *term = it->item;
|
||||||
render_resize(term, term->width / term->scale, term->height / term->scale);
|
int scale = term->scale;
|
||||||
|
|
||||||
|
render_resize(term, term->width / scale, term->height / scale, true);
|
||||||
wayl_reload_cursor_theme(mon->wayl, term);
|
wayl_reload_cursor_theme(mon->wayl, term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -368,7 +370,8 @@ surface_enter(void *data, struct wl_surface *wl_surface,
|
||||||
tll_push_back(term->window->on_outputs, &it->item);
|
tll_push_back(term->window->on_outputs, &it->item);
|
||||||
|
|
||||||
/* Resize, since scale-to-use may have changed */
|
/* Resize, since scale-to-use may have changed */
|
||||||
render_resize(term, term->width / term->scale, term->height / term->scale);
|
int scale = term->scale;
|
||||||
|
render_resize(term, term->width / scale, term->height / scale, true);
|
||||||
wayl_reload_cursor_theme(wayl, term);
|
wayl_reload_cursor_theme(wayl, term);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -392,7 +395,8 @@ surface_leave(void *data, struct wl_surface *wl_surface,
|
||||||
tll_remove(term->window->on_outputs, it);
|
tll_remove(term->window->on_outputs, it);
|
||||||
|
|
||||||
/* Resize, since scale-to-use may have changed */
|
/* Resize, since scale-to-use may have changed */
|
||||||
render_resize(term, term->width / term->scale, term->height / term->scale);
|
int scale = term->scale;
|
||||||
|
render_resize(term, term->width / scale, term->height / scale, true);
|
||||||
wayl_reload_cursor_theme(wayl, term);
|
wayl_reload_cursor_theme(wayl, term);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -409,14 +413,68 @@ static void
|
||||||
xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
||||||
int32_t width, int32_t height, struct wl_array *states)
|
int32_t width, int32_t height, struct wl_array *states)
|
||||||
{
|
{
|
||||||
LOG_DBG("xdg-toplevel: configure: %dx%d", width, height);
|
bool is_focused = false;
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
char state_str[2048];
|
||||||
|
int state_chars = 0;
|
||||||
|
|
||||||
if (width <= 0 || height <= 0)
|
static const char *const strings[] = {
|
||||||
return;
|
[XDG_TOPLEVEL_STATE_MAXIMIZED] = "maximized",
|
||||||
|
[XDG_TOPLEVEL_STATE_FULLSCREEN] = "fullscreen",
|
||||||
|
[XDG_TOPLEVEL_STATE_RESIZING] = "resizing",
|
||||||
|
[XDG_TOPLEVEL_STATE_ACTIVATED] = "activated",
|
||||||
|
[XDG_TOPLEVEL_STATE_TILED_LEFT] = "tiled:left",
|
||||||
|
[XDG_TOPLEVEL_STATE_TILED_RIGHT] = "tiled:right",
|
||||||
|
[XDG_TOPLEVEL_STATE_TILED_TOP] = "tiled:top",
|
||||||
|
[XDG_TOPLEVEL_STATE_TILED_BOTTOM] = "tiled:bottom",
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum xdg_toplevel_state *state;
|
||||||
|
wl_array_for_each(state, states) {
|
||||||
|
switch (*state) {
|
||||||
|
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
||||||
|
is_focused = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XDG_TOPLEVEL_STATE_MAXIMIZED:
|
||||||
|
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
||||||
|
case XDG_TOPLEVEL_STATE_RESIZING:
|
||||||
|
case XDG_TOPLEVEL_STATE_TILED_LEFT:
|
||||||
|
case XDG_TOPLEVEL_STATE_TILED_RIGHT:
|
||||||
|
case XDG_TOPLEVEL_STATE_TILED_TOP:
|
||||||
|
case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
|
||||||
|
/* Ignored */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
if (*state >= XDG_TOPLEVEL_STATE_MAXIMIZED &&
|
||||||
|
*state <= XDG_TOPLEVEL_STATE_TILED_BOTTOM)
|
||||||
|
{
|
||||||
|
state_chars += snprintf(
|
||||||
|
&state_str[state_chars], sizeof(state_str) - state_chars,
|
||||||
|
"%s, ", strings[*state]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state_chars > 2)
|
||||||
|
state_str[state_chars - 2] = '\0';
|
||||||
|
|
||||||
|
LOG_DBG("xdg-toplevel: configure: size=%dx%d, states=%s",
|
||||||
|
width, height, state_str);
|
||||||
|
|
||||||
struct wayland *wayl = data;
|
struct wayland *wayl = data;
|
||||||
struct terminal *term = wayl_terminal_from_xdg_toplevel(wayl, xdg_toplevel);
|
struct terminal *term = wayl_terminal_from_xdg_toplevel(wayl, xdg_toplevel);
|
||||||
render_resize(term, width, height);
|
|
||||||
|
if (is_focused)
|
||||||
|
term_visual_focus_in(term);
|
||||||
|
else
|
||||||
|
term_visual_focus_out(term);
|
||||||
|
|
||||||
|
if (width > 0 && height > 0)
|
||||||
|
render_resize(term, width, height, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -437,8 +495,23 @@ static void
|
||||||
xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
|
xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
|
||||||
uint32_t serial)
|
uint32_t serial)
|
||||||
{
|
{
|
||||||
//LOG_DBG("xdg-surface: configure");
|
LOG_DBG("xdg-surface: configure");
|
||||||
xdg_surface_ack_configure(xdg_surface, serial);
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Changes done in e.g. xdg-toplevel-configure will be ignored
|
||||||
|
* since the 'configure' event hasn't been ack:ed yet.
|
||||||
|
*
|
||||||
|
* Unfortunately, *this* function is called *last*, meaning we
|
||||||
|
* have no way of acking the configure before we resize the
|
||||||
|
* terminal in xdg-toplevel-configure.
|
||||||
|
*
|
||||||
|
* So, refresh here, to ensure changes take effect as soon as possible.
|
||||||
|
*/
|
||||||
|
struct wayland *wayl = data;
|
||||||
|
struct terminal *term = wayl_terminal_from_xdg_surface(wayl, xdg_surface);
|
||||||
|
if (term->width > 0 && term->height > 0)
|
||||||
|
render_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||||
|
|
@ -787,8 +860,6 @@ wayl_win_init(struct wayland *wayl)
|
||||||
wl_subsurface_set_desync(win->search_sub_surface);
|
wl_subsurface_set_desync(win->search_sub_surface);
|
||||||
|
|
||||||
wl_surface_commit(win->surface);
|
wl_surface_commit(win->surface);
|
||||||
wl_display_roundtrip(wayl->display);
|
|
||||||
|
|
||||||
return win;
|
return win;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
@ -849,12 +920,12 @@ wayl_cursor_set(struct wayland *wayl, const struct terminal *term)
|
||||||
if (wayl->pointer.theme == NULL)
|
if (wayl->pointer.theme == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (wayl->moused == NULL) {
|
if (wayl->mouse_focus == NULL) {
|
||||||
wayl->pointer.xcursor = NULL;
|
wayl->pointer.xcursor = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wayl->moused != term) {
|
if (wayl->mouse_focus != term) {
|
||||||
/* This terminal doesn't have mouse focus */
|
/* This terminal doesn't have mouse focus */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -932,6 +1003,19 @@ wayl_terminal_from_surface(struct wayland *wayl, struct wl_surface *surface)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct terminal *
|
||||||
|
wayl_terminal_from_xdg_surface(struct wayland *wayl,
|
||||||
|
struct xdg_surface *surface)
|
||||||
|
{
|
||||||
|
tll_foreach(wayl->terms, it) {
|
||||||
|
if (it->item->window->xdg_surface == surface)
|
||||||
|
return it->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct terminal *
|
struct terminal *
|
||||||
wayl_terminal_from_xdg_toplevel(struct wayland *wayl,
|
wayl_terminal_from_xdg_toplevel(struct wayland *wayl,
|
||||||
struct xdg_toplevel *toplevel)
|
struct xdg_toplevel *toplevel)
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,8 @@ struct wayland {
|
||||||
tll(struct monitor) monitors; /* All available outputs */
|
tll(struct monitor) monitors; /* All available outputs */
|
||||||
|
|
||||||
tll(struct terminal *) terms;
|
tll(struct terminal *) terms;
|
||||||
struct terminal *focused;
|
struct terminal *kbd_focus;
|
||||||
struct terminal *moused;
|
struct terminal *mouse_focus;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wayland *wayl_init(const struct config *conf, struct fdm *fdm);
|
struct wayland *wayl_init(const struct config *conf, struct fdm *fdm);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue