mirror of
https://codeberg.org/dwl/dwl.git
synced 2025-10-28 10:34:50 +00:00
adopt dwl/suckless style
also merge main and wlroots-next requires swaywm/wlroots@30d3c76
This commit is contained in:
parent
fe1764e328
commit
52a061dbda
416
dwl.c
416
dwl.c
@ -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
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user