adopt dwl/suckless style

also merge main and wlroots-next
requires swaywm/wlroots@30d3c76
This commit is contained in:
Leonardo Hernandez Hernandez 2021-10-10 19:34:33 -05:00
parent fe1764e328
commit 52a061dbda
No known key found for this signature in database
GPG Key ID: E538897EE11B9624

416
dwl.c
View File

@ -215,9 +215,9 @@ typedef struct {
* in the focused state, wl_keyboard sent an enter as well. However, having
* wl_keyboard focused doesn't mean that text-input will be focused.
*/
struct dwl_input_method_relay {
struct wl_list text_inputs; // dwl_text_input::link
struct wl_list input_popups; // dwl_input_popup::link
typedef struct {
struct wl_list text_inputs; // TextInput::link
struct wl_list input_popups; // InputPopup::link
struct wlr_input_method_v2 *input_method; // doesn't have to be present
struct wl_listener text_input_new;
@ -228,10 +228,10 @@ struct dwl_input_method_relay {
struct wl_listener input_method_new_popup_surface;
struct wl_listener input_method_grab_keyboard;
struct wl_listener input_method_keyboard_grab_destroy;
};
} InputMethodRelay;
struct dwl_text_input {
struct dwl_input_method_relay *relay;
typedef struct {
InputMethodRelay *relay;
struct wlr_text_input_v3 *input;
// The surface getting seat's focus. Stored for when text-input cannot
@ -247,11 +247,10 @@ struct dwl_text_input {
struct wl_listener text_input_commit;
struct wl_listener text_input_disable;
struct wl_listener text_input_destroy;
};
} TextInput;
struct dwl_input_popup {
struct dwl_input_method_relay *relay;
typedef struct {
InputMethodRelay *relay;
struct wlr_input_popup_surface_v2 *popup_surface;
int x, y;
@ -265,7 +264,7 @@ struct dwl_input_popup {
struct wl_listener popup_destroy;
struct wl_listener popup_surface_commit;
struct wl_listener focused_surface_unmap;
};
} InputPopup;
/* Used to move all of the data necessary to render a surface from the top-level
* frame handler to the per-surface render function. */
@ -302,14 +301,33 @@ static void createpointer(struct wlr_input_device *device);
static void cursorframe(struct wl_listener *listener, void *data);
static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
static void destroynotify(struct wl_listener *listener, void *data);
static void destroypendingfocusedsurface(struct wl_listener *listener, void *data);
static Monitor *dirtomon(enum wlr_direction dir);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
static void fullscreennotify(struct wl_listener *listener, void *data);
static Client *focustop(Monitor *m);
static void getparentandoutputbox(struct wlr_surface *focused_surface,
struct wlr_box *parent, struct wlr_box *output_box);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
static void inputmethodrelaysetfocus(InputMethodRelay *relay, struct wlr_surface *surface);
static TextInput *textinputcreate(InputMethodRelay *relay,
struct wlr_text_input_v3 *text_input);
static void inputmethodgrabkeyboard(struct wl_listener *listener, void *data);
static void inputmethodkeyboardgrabdestroy(struct wl_listener *listener, void *data);
static void inputmethodcommit(struct wl_listener *listener, void *data);
static void inputmethodfocusedsurfacedestroy(struct wl_listener *listener, void *data);
static void inputmethoddestroy(struct wl_listener *listener, void *data);
static void inputmethodrelaysetfocus(InputMethodRelay *relay, struct wlr_surface *surface);
static void inputpopupsetfocus(InputPopup *popup, struct wlr_surface *surface);
static void inputpopupsendoutputs(InputPopup *popup, wlr_surface_iterator_func_t iterator);
static void inputmethodnewpopupsurface(struct wl_listener *listener, void *data);
static void inputmethodpopupdestroy(struct wl_listener *listener, void *data);
static void inputmethodpopupmap(struct wl_listener *listener, void *data);
static void inputmethodpopupunmap(struct wl_listener *listener, void *data);
static void inputmethodpopupsurfacecommit(struct wl_listener *listener, void *data);
static int keybinding(uint32_t mods, xkb_keysym_t sym);
static void keypress(struct wl_listener *listener, void *data);
static void keypressmod(struct wl_listener *listener, void *data);
@ -329,6 +347,12 @@ static void pointerfocus(Client *c, struct wlr_surface *surface,
static void printstatus(void);
static void quit(const Arg *arg);
static void quitsignal(int signo);
static void relaycreateinputmethod(struct wl_listener *listener, void *data);
static void relaycreatetextinput(struct wl_listener *listener, void *data);
static void relaydisabletextinput(InputMethodRelay *relay, TextInput *text_input);
static TextInput *relaygetfocusabletextinput(InputMethodRelay *relay);
static TextInput *relaygetfocusedtextinput(InputMethodRelay *relay);
static void relaysendinputmethodstate(InputMethodRelay *relay, struct wlr_text_input_v3 *input);
static void render(struct wlr_surface *surface, int sx, int sy, void *data);
static void renderclients(Monitor *m, struct timespec *now);
static void renderlayer(struct wl_list *layer_surfaces, struct timespec *now);
@ -348,8 +372,17 @@ static void setmon(Client *c, Monitor *m, unsigned int newtags);
static void setup(void);
static void sigchld(int unused);
static void spawn(const Arg *arg);
static void surfacesendenter(struct wlr_surface *surface, int x, int y, void *data);
static void surfacesendleave(struct wlr_surface *surface, int x, int y, void *data);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void textinputcommit(struct wl_listener *listener, void *data);
static TextInput *textinputcreate(InputMethodRelay *relay, struct wlr_text_input_v3 *text_input);
static void textinputenable(struct wl_listener *listener, void *data);
static void textinputdestroy(struct wl_listener *listener, void *data);
static void textinputdisable(struct wl_listener *listener, void *data);
static void textinputsetpendingfocusedsurface(TextInput *text_input,
struct wlr_surface *surface);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
@ -358,6 +391,7 @@ static void toggleview(const Arg *arg);
static void unmaplayersurface(LayerSurface *layersurface);
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
static void unmapnotify(struct wl_listener *listener, void *data);
static void updateinputpopup(InputPopup *popup);
static void updatemons(struct wl_listener *listener, void *data);
static void updatetitle(struct wl_listener *listener, void *data);
static void urgent(struct wl_listener *listener, void *data);
@ -367,17 +401,6 @@ static Client *xytoclient(double x, double y);
static struct wlr_surface *xytolayersurface(struct wl_list *layer_surfaces,
double x, double y, double *sx, double *sy);
static Monitor *xytomon(double x, double y);
void dwl_input_method_relay_init(struct dwl_input_method_relay *relay);
// Updates currently focused surface. Surface must belong to the same
// seat.
void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay,
struct wlr_surface *surface);
struct dwl_text_input *dwl_text_input_create(
struct dwl_input_method_relay *relay,
struct wlr_text_input_v3 *text_input);
static void handle_im_grab_keyboard(struct wl_listener *listener, void *data);
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener,
void *data);
static void zoom(const Arg *arg);
/* variables */
@ -393,7 +416,7 @@ static struct wl_list clients; /* tiling order */
static struct wl_list fstack; /* focus order */
static struct wl_list stack; /* stacking z-order */
static struct wl_list independents;
static struct wl_list input_popups; /* dwl_input_popup::view_link to be rendered for the input method */
static struct wl_list input_popups; /* InputPopup::view_link to be rendered for the input method */
static struct wlr_idle *idle;
static struct wlr_layer_shell_v1 *layer_shell;
static struct wlr_output_manager_v1 *output_mgr;
@ -404,9 +427,9 @@ static struct wlr_cursor *cursor;
static struct wlr_xcursor_manager *cursor_mgr;
static struct wlr_seat *seat;
struct wlr_input_method_manager_v2 *input_method_manager;
struct wlr_text_input_manager_v3 *text_input_manager;
struct dwl_input_method_relay *input_relay;
struct wlr_input_method_manager_v2 *input_method_mgr;
struct wlr_text_input_manager_v3 *text_input_mgr;
InputMethodRelay *input_relay;
static struct wl_list keyboards;
static unsigned int cursor_mode;
static Client *grabc;
@ -1203,7 +1226,7 @@ focusclient(Client *c, int lift)
kb = wlr_seat_get_keyboard(seat);
wlr_seat_keyboard_notify_enter(seat, client_surface(c),
kb->keycodes, kb->num_keycodes, &kb->modifiers);
dwl_input_method_relay_set_focus(input_relay, client_surface(c));
inputmethodrelaysetfocus(input_relay, client_surface(c));
/* Activate the new client */
client_activate_surface(client_surface(c), 1);
@ -1444,8 +1467,10 @@ mapnotify(struct wl_listener *listener, void *data)
applyrules(c);
}
static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
void
inputmethodgrabkeyboard(struct wl_listener *listener, void *data)
{
InputMethodRelay *relay = wl_container_of(listener, relay,
input_method_grab_keyboard);
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
@ -1459,11 +1484,13 @@ static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
wl_signal_add(&keyboard_grab->events.destroy,
&relay->input_method_keyboard_grab_destroy);
relay->input_method_keyboard_grab_destroy.notify =
handle_im_keyboard_grab_destroy;
inputmethodkeyboardgrabdestroy;
}
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, void *data) {
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
void
inputmethodkeyboardgrabdestroy(struct wl_listener *listener, void *data)
{
InputMethodRelay *relay = wl_container_of(listener, relay,
input_method_keyboard_grab_destroy);
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
@ -1887,7 +1914,7 @@ void
render_input_popups(struct wlr_output* output, struct wl_list *input_popups,
struct timespec *now)
{
struct dwl_input_popup *popup;
InputPopup *popup;
wl_list_for_each(popup, input_popups, view_link) {
struct render_data rdata = {
@ -2157,9 +2184,10 @@ setsel(struct wl_listener *listener, void *data)
}
// text-input-, and input_method-relevant functions
static struct dwl_text_input *relay_get_focusable_text_input(
struct dwl_input_method_relay *relay) {
struct dwl_text_input *text_input = NULL;
TextInput *
relaygetfocusabletextinput(InputMethodRelay *relay)
{
TextInput *text_input = NULL;
wl_list_for_each(text_input, &relay->text_inputs, link) {
if (text_input->pending_focused_surface) {
return text_input;
@ -2168,9 +2196,10 @@ static struct dwl_text_input *relay_get_focusable_text_input(
return NULL;
}
static struct dwl_text_input *relay_get_focused_text_input(
struct dwl_input_method_relay *relay) {
struct dwl_text_input *text_input = NULL;
TextInput *
relaygetfocusedtextinput(InputMethodRelay *relay)
{
TextInput *text_input = NULL;
wl_list_for_each(text_input, &relay->text_inputs, link) {
if (text_input->input->focused_surface) {
return text_input;
@ -2179,13 +2208,15 @@ static struct dwl_text_input *relay_get_focused_text_input(
return NULL;
}
static void handle_im_commit(struct wl_listener *listener, void *data) {
void
inputmethodcommit(struct wl_listener *listener, void *data)
{
struct wlr_input_method_v2 *context;
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
InputMethodRelay *relay = wl_container_of(listener, relay,
input_method_commit);
struct dwl_text_input *text_input = relay_get_focused_text_input(relay);
TextInput *text_input = relaygetfocusedtextinput(relay);
if (!text_input) {
return;
}
@ -2211,8 +2242,10 @@ static void handle_im_commit(struct wl_listener *listener, void *data) {
wlr_text_input_v3_send_done(text_input->input);
}
static void text_input_set_pending_focused_surface(
struct dwl_text_input *text_input, struct wlr_surface *surface) {
void
textinputsetpendingfocusedsurface(
TextInput *text_input, struct wlr_surface *surface)
{
wl_list_remove(&text_input->pending_focused_surface_destroy.link);
text_input->pending_focused_surface = surface;
@ -2224,27 +2257,31 @@ static void text_input_set_pending_focused_surface(
}
}
static void handle_im_destroy(struct wl_listener *listener, void *data) {
struct dwl_text_input *text_input;
void
inputmethoddestroy(struct wl_listener *listener, void *data)
{
TextInput *text_input;
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
InputMethodRelay *relay = wl_container_of(listener, relay,
input_method_destroy);
struct wlr_input_method_v2 *context = data;
assert(context == relay->input_method);
relay->input_method = NULL;
text_input = relay_get_focused_text_input(relay);
text_input = relaygetfocusedtextinput(relay);
if (text_input) {
// keyboard focus is still there, so keep the surface at hand in case
// the input method returns
text_input_set_pending_focused_surface(text_input,
textinputsetpendingfocusedsurface(text_input,
text_input->input->focused_surface);
wlr_text_input_v3_send_leave(text_input->input);
}
}
static void relay_send_im_state(struct dwl_input_method_relay *relay,
struct wlr_text_input_v3 *input) {
void
relaysendinputmethodstate(InputMethodRelay *relay,
struct wlr_text_input_v3 *input)
{
struct wlr_input_method_v2 *input_method = relay->input_method;
if (!input_method) {
wlr_log(WLR_INFO, "Sending IM_DONE but im is gone");
@ -2262,20 +2299,23 @@ static void relay_send_im_state(struct dwl_input_method_relay *relay,
// TODO: pass intent, display popup size
}
static void handle_text_input_enable(struct wl_listener *listener, void *data) {
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
void
textinputenable(struct wl_listener *listener, void *data)
{
TextInput *text_input = wl_container_of(listener, text_input,
text_input_enable);
if (text_input->relay->input_method == NULL) {
wlr_log(WLR_INFO, "Enabling text input when input method is gone");
return;
}
wlr_input_method_v2_send_activate(text_input->relay->input_method);
relay_send_im_state(text_input->relay, text_input->input);
relaysendinputmethodstate(text_input->relay, text_input->input);
}
static void handle_text_input_commit(struct wl_listener *listener,
void *data) {
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
void
textinputcommit(struct wl_listener *listener, void *data)
{
TextInput *text_input = wl_container_of(listener, text_input,
text_input_commit);
if (!text_input->input->current_enabled) {
wlr_log(WLR_INFO, "Inactive text input tried to commit an update");
@ -2286,35 +2326,38 @@ static void handle_text_input_commit(struct wl_listener *listener,
wlr_log(WLR_INFO, "Text input committed, but input method is gone");
return;
}
relay_send_im_state(text_input->relay, text_input->input);
relaysendinputmethodstate(text_input->relay, text_input->input);
}
static void relay_disable_text_input(struct dwl_input_method_relay *relay,
struct dwl_text_input *text_input) {
void
relaydisabletextinput(InputMethodRelay *relay, TextInput *text_input)
{
if (relay->input_method == NULL) {
wlr_log(WLR_DEBUG, "Disabling text input, but input method is gone");
return;
}
wlr_input_method_v2_send_deactivate(relay->input_method);
relay_send_im_state(relay, text_input->input);
relaysendinputmethodstate(relay, text_input->input);
}
static void handle_text_input_disable(struct wl_listener *listener,
void *data) {
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
void
textinputdisable(struct wl_listener *listener, void *data)
{
TextInput *text_input = wl_container_of(listener, text_input,
text_input_disable);
relay_disable_text_input(text_input->relay, text_input);
relaydisabletextinput(text_input->relay, text_input);
}
static void handle_text_input_destroy(struct wl_listener *listener,
void *data) {
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
void
textinputdestroy(struct wl_listener *listener, void *data)
{
TextInput *text_input = wl_container_of(listener, text_input,
text_input_destroy);
if (text_input->input->current_enabled) {
relay_disable_text_input(text_input->relay, text_input);
relaydisabletextinput(text_input->relay, text_input);
}
text_input_set_pending_focused_surface(text_input, NULL);
textinputsetpendingfocusedsurface(text_input, NULL);
wl_list_remove(&text_input->text_input_commit.link);
wl_list_remove(&text_input->text_input_destroy.link);
wl_list_remove(&text_input->text_input_disable.link);
@ -2323,9 +2366,10 @@ static void handle_text_input_destroy(struct wl_listener *listener,
free(text_input);
}
static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
void *data) {
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
void
destroypendingfocusedsurface(struct wl_listener *listener, void *data)
{
TextInput *text_input = wl_container_of(listener, text_input,
pending_focused_surface_destroy);
struct wlr_surface *surface = data;
assert(text_input->pending_focused_surface == surface);
@ -2334,10 +2378,10 @@ static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
wl_list_init(&text_input->pending_focused_surface_destroy.link);
}
struct dwl_text_input *dwl_text_input_create(
struct dwl_input_method_relay *relay,
struct wlr_text_input_v3 *text_input) {
struct dwl_text_input *input;
TextInput *
textinputcreate(InputMethodRelay *relay, struct wlr_text_input_v3 *text_input)
{
TextInput *input;
input = calloc(1, sizeof(*input));
if (!input) {
return NULL;
@ -2347,53 +2391,45 @@ struct dwl_text_input *dwl_text_input_create(
wl_list_insert(&relay->text_inputs, &input->link);
input->text_input_enable.notify = handle_text_input_enable;
input->text_input_enable.notify = textinputenable;
wl_signal_add(&text_input->events.enable, &input->text_input_enable);
input->text_input_commit.notify = handle_text_input_commit;
input->text_input_commit.notify = textinputcommit;
wl_signal_add(&text_input->events.commit, &input->text_input_commit);
input->text_input_disable.notify = handle_text_input_disable;
input->text_input_disable.notify = textinputdisable;
wl_signal_add(&text_input->events.disable, &input->text_input_disable);
input->text_input_destroy.notify = handle_text_input_destroy;
input->text_input_destroy.notify = textinputdestroy;
wl_signal_add(&text_input->events.destroy, &input->text_input_destroy);
input->pending_focused_surface_destroy.notify =
handle_pending_focused_surface_destroy;
destroypendingfocusedsurface;
wl_list_init(&input->pending_focused_surface_destroy.link);
return input;
}
static void relay_handle_text_input(struct wl_listener *listener,
void *data) {
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
void
relaycreatetextinput(struct wl_listener *listener, void *data)
{
InputMethodRelay *relay = wl_container_of(listener, relay,
text_input_new);
struct wlr_text_input_v3 *wlr_text_input = data;
if (seat != wlr_text_input->seat) {
return;
}
dwl_text_input_create(relay, wlr_text_input);
textinputcreate(relay, wlr_text_input);
}
static LayerSurface* layer_surface_from_wlr_layer_surface_v1(
struct wlr_layer_surface_v1* layer_surface) {
return layer_surface->data;
}
static Client* client_from_wlr_surface(struct wlr_surface* surface) {
return surface->data;
}
static void input_popup_send_outputs(struct dwl_input_popup *popup,
wlr_surface_iterator_func_t iterator) {
void
inputpopupsendoutputs(InputPopup *popup, wlr_surface_iterator_func_t iterator)
{
struct wlr_surface* focused_surface;
struct wlr_output* output;
Client* client;
struct dwl_text_input *text_input =
relay_get_focused_text_input(popup->relay);
TextInput *text_input = relaygetfocusedtextinput(popup->relay);
if (!text_input || !text_input->input->focused_surface) {
return;
}
@ -2407,41 +2443,44 @@ static void input_popup_send_outputs(struct dwl_input_popup *popup,
return;
}
client = client_from_wlr_surface(focused_surface);
client = focused_surface->data;
output = client->mon->wlr_output;
wlr_surface_for_each_surface(popup->popup_surface->surface,
iterator, output);
}
static void surface_send_enter_iterator(struct wlr_surface *surface,
int x, int y, void *data) {
void
surfacesendenter(struct wlr_surface *surface, int x, int y, void *data)
{
struct wlr_output *wlr_output = data;
wlr_surface_send_enter(surface, wlr_output);
}
static void surface_send_leave_iterator(struct wlr_surface *surface,
int x, int y, void *data) {
void
surfacesendleave(struct wlr_surface *surface, int x, int y, void *data)
{
struct wlr_output *wlr_output = data;
wlr_surface_send_leave(surface, wlr_output);
}
static void get_parent_and_output_box(struct wlr_surface *focused_surface,
struct wlr_box *parent, struct wlr_box *output_box) {
void
getparentandoutputbox(struct wlr_surface *focused_surface,
struct wlr_box *parent, struct wlr_box *output_box)
{
struct wlr_output *output;
struct wlr_box *output_box_tmp;
if (wlr_surface_is_layer_surface(focused_surface)) {
struct wlr_layer_surface_v1 *layer_surface =
wlr_layer_surface_v1_from_wlr_surface(focused_surface);
LayerSurface* layer =
layer_surface_from_wlr_layer_surface_v1(layer_surface);
LayerSurface* layer = layer_surface->data;
output = layer->layer_surface->output;
output_box_tmp = wlr_output_layout_get_box(output_layout, output);
*parent = layer->geo;
parent->x += output_box_tmp->x;
parent->y += output_box_tmp->y;
} else {
Client *client = client_from_wlr_surface(focused_surface);
Client *client = focused_surface->data;
output = wlr_output_layout_output_at(output_layout,
client->geom.x, client->geom.y);
output_box_tmp = wlr_output_layout_get_box(output_layout, output);
@ -2454,15 +2493,17 @@ static void get_parent_and_output_box(struct wlr_surface *focused_surface,
*output_box = *output_box_tmp;
}
static void input_popup_update(struct dwl_input_popup *popup) {
void
updateinputpopup(InputPopup *popup)
{
struct wlr_surface* focused_surface;
struct wlr_box output_box, parent, cursor;
int x1, x2, y1, y2, x, y, available_right, available_left, available_down,
available_up, popup_width, popup_height;
bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds;
struct dwl_text_input *text_input =
relay_get_focused_text_input(popup->relay);
TextInput *text_input =
relaygetfocusedtextinput(popup->relay);
if (!text_input|| !text_input->input->focused_surface) {
return;
}
@ -2476,7 +2517,7 @@ static void input_popup_update(struct dwl_input_popup *popup) {
focused_surface = text_input->input->focused_surface;
cursor = text_input->input->current.cursor_rectangle;
get_parent_and_output_box(focused_surface, &parent, &output_box);
getparentandoutputbox(focused_surface, &parent, &output_box);
if (!cursor_rect) {
cursor.x = 0;
@ -2531,22 +2572,28 @@ static void input_popup_update(struct dwl_input_popup *popup) {
}
}
static void handle_im_popup_map(struct wl_listener *listener, void *data) {
struct dwl_input_popup *popup =
void
inputmethodpopupmap(struct wl_listener *listener, void *data)
{
InputPopup *popup =
wl_container_of(listener, popup, popup_map);
input_popup_send_outputs(popup, surface_send_enter_iterator);
input_popup_update(popup);
inputpopupsendoutputs(popup, surfacesendenter);
updateinputpopup(popup);
}
static void handle_im_popup_unmap(struct wl_listener *listener, void *data) {
struct dwl_input_popup *popup =
void
inputmethodpopupunmap(struct wl_listener *listener, void *data)
{
InputPopup *popup =
wl_container_of(listener, popup, popup_unmap);
input_popup_send_outputs(popup, surface_send_leave_iterator);
input_popup_update(popup);
inputpopupsendoutputs(popup, surfacesendleave);
updateinputpopup(popup);
}
static void handle_im_popup_destroy(struct wl_listener *listener, void *data) {
struct dwl_input_popup *popup =
void
inputmethodpopupdestroy(struct wl_listener *listener, void *data)
{
InputPopup *popup =
wl_container_of(listener, popup, popup_destroy);
wl_list_remove(&popup->focused_surface_unmap.link);
wl_list_remove(&popup->popup_surface_commit.link);
@ -2558,56 +2605,64 @@ static void handle_im_popup_destroy(struct wl_listener *listener, void *data) {
free(popup);
}
static void handle_im_popup_surface_commit(struct wl_listener *listener,
void *data) {
struct dwl_input_popup *popup =
void
inputmethodpopupsurfacecommit(struct wl_listener *listener, void *data)
{
InputPopup *popup =
wl_container_of(listener, popup, popup_surface_commit);
input_popup_update(popup);
updateinputpopup(popup);
}
static void handle_im_focused_surface_destroy(
struct wl_listener *listener, void *data) {
struct dwl_input_popup *popup =
void
inputmethodfocusedsurfacedestroy(struct wl_listener *listener, void *data)
{
InputPopup *popup =
wl_container_of(listener, popup, focused_surface_unmap);
wl_list_remove(&popup->view_link);
wl_list_init(&popup->view_link);
input_popup_update(popup);
updateinputpopup(popup);
}
static void input_popup_set_focus(struct dwl_input_popup *popup,
struct wlr_surface *surface) {
void
inputpopupsetfocus(InputPopup *popup, struct wlr_surface *surface)
{
Client* client;
struct wlr_layer_surface_v1* layer_surface;
LayerSurface* layer;
if (!surface)
return;
wl_list_remove(&popup->view_link);
wl_list_remove(&popup->focused_surface_unmap.link);
if (wlr_surface_is_layer_surface(surface)) {
layer_surface = wlr_layer_surface_v1_from_wlr_surface(surface);
layer = layer_surface_from_wlr_layer_surface_v1(layer_surface);
layer = layer_surface->data;
wl_list_insert(&input_popups, &popup->view_link);
wl_signal_add(&layer->layer_surface->events.unmap,
&popup->focused_surface_unmap);
input_popup_update(popup);
updateinputpopup(popup);
return;
}
client = client_from_wlr_surface(surface);
client = surface->data;
wl_list_insert(&input_popups, &popup->view_link);
wl_signal_add(&client->surface.xdg->events.unmap,
&popup->focused_surface_unmap);
input_popup_update(popup);
updateinputpopup(popup);
}
static void handle_im_new_popup_surface(struct wl_listener *listener, void *data) {
struct dwl_text_input* text_input;
void
inputmethodnewpopupsurface(struct wl_listener *listener, void *data)
{
TextInput* text_input;
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
InputMethodRelay *relay = wl_container_of(listener, relay,
input_method_new_popup_surface);
struct dwl_input_popup *popup = calloc(1, sizeof(*popup));
InputPopup *popup = calloc(1, sizeof(*popup));
popup->relay = relay;
popup->popup_surface = data;
popup->popup_surface->data = popup;
@ -2615,39 +2670,40 @@ static void handle_im_new_popup_surface(struct wl_listener *listener, void *data
wl_list_init(&popup->view_link);
wl_signal_add(&popup->popup_surface->events.map, &popup->popup_map);
popup->popup_map.notify = handle_im_popup_map;
popup->popup_map.notify = inputmethodpopupmap;
wl_signal_add(
&popup->popup_surface->events.unmap, &popup->popup_unmap);
popup->popup_unmap.notify = handle_im_popup_unmap;
popup->popup_unmap.notify = inputmethodpopupunmap;
wl_signal_add(
&popup->popup_surface->events.destroy, &popup->popup_destroy);
popup->popup_destroy.notify = handle_im_popup_destroy;
popup->popup_destroy.notify = inputmethodpopupdestroy;
wl_signal_add(&popup->popup_surface->surface->events.commit,
&popup->popup_surface_commit);
popup->popup_surface_commit.notify = handle_im_popup_surface_commit;
popup->popup_surface_commit.notify = inputmethodpopupsurfacecommit;
wl_list_init(&popup->focused_surface_unmap.link);
popup->focused_surface_unmap.notify = handle_im_focused_surface_destroy;
popup->focused_surface_unmap.notify = inputmethodfocusedsurfacedestroy;
text_input = relay_get_focused_text_input(relay);
text_input = relaygetfocusedtextinput(relay);
if (text_input) {
input_popup_set_focus(popup, text_input->input->focused_surface);
inputpopupsetfocus(popup, text_input->input->focused_surface);
} else {
input_popup_set_focus(popup, NULL);
inputpopupsetfocus(popup, NULL);
}
wl_list_insert(&relay->input_popups, &popup->link);
}
static void relay_handle_input_method(struct wl_listener *listener,
void *data) {
struct dwl_text_input *text_input;
void
relaycreateinputmethod(struct wl_listener *listener, void *data)
{
TextInput *text_input;
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
InputMethodRelay *relay = wl_container_of(listener, relay,
input_method_new);
struct wlr_input_method_v2 *input_method = data;
@ -2664,51 +2720,39 @@ static void relay_handle_input_method(struct wl_listener *listener,
relay->input_method = input_method;
wl_signal_add(&relay->input_method->events.commit,
&relay->input_method_commit);
relay->input_method_commit.notify = handle_im_commit;
relay->input_method_commit.notify = inputmethodcommit;
wl_signal_add(&relay->input_method->events.new_popup_surface,
&relay->input_method_new_popup_surface);
relay->input_method_new_popup_surface.notify = handle_im_new_popup_surface;
relay->input_method_new_popup_surface.notify = inputmethodnewpopupsurface;
wl_signal_add(&relay->input_method->events.grab_keyboard,
&relay->input_method_grab_keyboard);
relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard;
relay->input_method_grab_keyboard.notify = inputmethodgrabkeyboard;
wl_signal_add(&relay->input_method->events.destroy,
&relay->input_method_destroy);
relay->input_method_destroy.notify = handle_im_destroy;
relay->input_method_destroy.notify = inputmethoddestroy;
text_input = relay_get_focusable_text_input(relay);
text_input = relaygetfocusabletextinput(relay);
if (text_input) {
wlr_text_input_v3_send_enter(text_input->input,
text_input->pending_focused_surface);
text_input_set_pending_focused_surface(text_input, NULL);
textinputsetpendingfocusedsurface(text_input, NULL);
}
}
void dwl_input_method_relay_init(struct dwl_input_method_relay *relay) {
wl_list_init(&relay->text_inputs);
wl_list_init(&relay->input_popups);
relay->text_input_new.notify = relay_handle_text_input;
wl_signal_add(&text_input_manager->events.text_input,
&relay->text_input_new);
relay->input_method_new.notify = relay_handle_input_method;
wl_signal_add(&input_method_manager->events.input_method,
&relay->input_method_new);
}
void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay,
struct wlr_surface *surface) {
struct dwl_text_input *text_input;
void
inputmethodrelaysetfocus(InputMethodRelay *relay, struct wlr_surface *surface)
{
TextInput *text_input;
wl_list_for_each(text_input, &relay->text_inputs, link) {
if (text_input->pending_focused_surface) {
assert(text_input->input->focused_surface == NULL);
if (surface != text_input->pending_focused_surface) {
text_input_set_pending_focused_surface(text_input, NULL);
textinputsetpendingfocusedsurface(text_input, NULL);
}
} else if (text_input->input->focused_surface) {
assert(text_input->pending_focused_surface == NULL);
if (surface != text_input->input->focused_surface) {
relay_disable_text_input(relay, text_input);
relaydisabletextinput(relay, text_input);
wlr_text_input_v3_send_leave(text_input->input);
} else {
wlr_log(WLR_DEBUG, "IM relay set_focus already focused");
@ -2722,7 +2766,7 @@ void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay,
if (relay->input_method) {
wlr_text_input_v3_send_enter(text_input->input, surface);
} else {
text_input_set_pending_focused_surface(text_input, surface);
textinputsetpendingfocusedsurface(text_input, surface);
}
}
}
@ -2870,11 +2914,21 @@ setup(void)
presentation = wlr_presentation_create(dpy, backend);
/* create text_input-, and input_method-protocol relevant globals */
input_method_manager = wlr_input_method_manager_v2_create(dpy);
text_input_manager = wlr_text_input_manager_v3_create(dpy);
input_method_mgr = wlr_input_method_manager_v2_create(dpy);
text_input_mgr = wlr_text_input_manager_v3_create(dpy);
input_relay = calloc(1, sizeof(*input_relay));
dwl_input_method_relay_init(input_relay);
wl_list_init(&input_relay->text_inputs);
wl_list_init(&input_relay->input_popups);
input_relay->text_input_new.notify = relaycreatetextinput;
wl_signal_add(&text_input_mgr->events.text_input,
&input_relay->text_input_new);
input_relay->input_method_new.notify = relaycreateinputmethod;
wl_signal_add(&input_method_mgr->events.input_method,
&input_relay->input_method_new);
#ifdef XWAYLAND
/*