mirror of
				https://codeberg.org/dwl/dwl.git
				synced 2025-11-04 05:54:14 +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
 | 
					 * 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.
 | 
					 * wl_keyboard focused doesn't mean that text-input will be focused.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct dwl_input_method_relay {
 | 
					typedef struct {
 | 
				
			||||||
	struct wl_list text_inputs; // dwl_text_input::link
 | 
						struct wl_list text_inputs; // TextInput::link
 | 
				
			||||||
	struct wl_list input_popups; // dwl_input_popup::link
 | 
						struct wl_list input_popups; // InputPopup::link
 | 
				
			||||||
	struct wlr_input_method_v2 *input_method; // doesn't have to be present
 | 
						struct wlr_input_method_v2 *input_method; // doesn't have to be present
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener text_input_new;
 | 
						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_new_popup_surface;
 | 
				
			||||||
	struct wl_listener input_method_grab_keyboard;
 | 
						struct wl_listener input_method_grab_keyboard;
 | 
				
			||||||
	struct wl_listener input_method_keyboard_grab_destroy;
 | 
						struct wl_listener input_method_keyboard_grab_destroy;
 | 
				
			||||||
};
 | 
					} InputMethodRelay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dwl_text_input {
 | 
					typedef struct {
 | 
				
			||||||
	struct dwl_input_method_relay *relay;
 | 
						InputMethodRelay *relay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_text_input_v3 *input;
 | 
						struct wlr_text_input_v3 *input;
 | 
				
			||||||
	// The surface getting seat's focus. Stored for when text-input cannot
 | 
						// 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_commit;
 | 
				
			||||||
	struct wl_listener text_input_disable;
 | 
						struct wl_listener text_input_disable;
 | 
				
			||||||
	struct wl_listener text_input_destroy;
 | 
						struct wl_listener text_input_destroy;
 | 
				
			||||||
};
 | 
					} TextInput;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
struct dwl_input_popup {
 | 
						InputMethodRelay *relay;
 | 
				
			||||||
	struct dwl_input_method_relay *relay;
 | 
					 | 
				
			||||||
	struct wlr_input_popup_surface_v2 *popup_surface;
 | 
						struct wlr_input_popup_surface_v2 *popup_surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int x, y;
 | 
						int x, y;
 | 
				
			||||||
@ -265,7 +264,7 @@ struct dwl_input_popup {
 | 
				
			|||||||
	struct wl_listener popup_destroy;
 | 
						struct wl_listener popup_destroy;
 | 
				
			||||||
	struct wl_listener popup_surface_commit;
 | 
						struct wl_listener popup_surface_commit;
 | 
				
			||||||
	struct wl_listener focused_surface_unmap;
 | 
						struct wl_listener focused_surface_unmap;
 | 
				
			||||||
};
 | 
					} InputPopup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Used to move all of the data necessary to render a surface from the top-level
 | 
					/* Used to move all of the data necessary to render a surface from the top-level
 | 
				
			||||||
 * frame handler to the per-surface render function. */
 | 
					 * 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 cursorframe(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void destroylayersurfacenotify(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 destroynotify(struct wl_listener *listener, void *data);
 | 
				
			||||||
 | 
					static void destroypendingfocusedsurface(struct wl_listener *listener, void *data);
 | 
				
			||||||
static Monitor *dirtomon(enum wlr_direction dir);
 | 
					static Monitor *dirtomon(enum wlr_direction dir);
 | 
				
			||||||
static void focusclient(Client *c, int lift);
 | 
					static void focusclient(Client *c, int lift);
 | 
				
			||||||
static void focusmon(const Arg *arg);
 | 
					static void focusmon(const Arg *arg);
 | 
				
			||||||
static void focusstack(const Arg *arg);
 | 
					static void focusstack(const Arg *arg);
 | 
				
			||||||
static void fullscreennotify(struct wl_listener *listener, void *data);
 | 
					static void fullscreennotify(struct wl_listener *listener, void *data);
 | 
				
			||||||
static Client *focustop(Monitor *m);
 | 
					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 incnmaster(const Arg *arg);
 | 
				
			||||||
static void inputdevice(struct wl_listener *listener, void *data);
 | 
					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 int keybinding(uint32_t mods, xkb_keysym_t sym);
 | 
				
			||||||
static void keypress(struct wl_listener *listener, void *data);
 | 
					static void keypress(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void keypressmod(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 printstatus(void);
 | 
				
			||||||
static void quit(const Arg *arg);
 | 
					static void quit(const Arg *arg);
 | 
				
			||||||
static void quitsignal(int signo);
 | 
					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 render(struct wlr_surface *surface, int sx, int sy, void *data);
 | 
				
			||||||
static void renderclients(Monitor *m, struct timespec *now);
 | 
					static void renderclients(Monitor *m, struct timespec *now);
 | 
				
			||||||
static void renderlayer(struct wl_list *layer_surfaces, 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 setup(void);
 | 
				
			||||||
static void sigchld(int unused);
 | 
					static void sigchld(int unused);
 | 
				
			||||||
static void spawn(const Arg *arg);
 | 
					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 tag(const Arg *arg);
 | 
				
			||||||
static void tagmon(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 tile(Monitor *m);
 | 
				
			||||||
static void togglefloating(const Arg *arg);
 | 
					static void togglefloating(const Arg *arg);
 | 
				
			||||||
static void togglefullscreen(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 unmaplayersurface(LayerSurface *layersurface);
 | 
				
			||||||
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
 | 
					static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void unmapnotify(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 updatemons(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void updatetitle(struct wl_listener *listener, void *data);
 | 
					static void updatetitle(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void urgent(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,
 | 
					static struct wlr_surface *xytolayersurface(struct wl_list *layer_surfaces,
 | 
				
			||||||
		double x, double y, double *sx, double *sy);
 | 
							double x, double y, double *sx, double *sy);
 | 
				
			||||||
static Monitor *xytomon(double x, double y);
 | 
					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);
 | 
					static void zoom(const Arg *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* variables */
 | 
					/* variables */
 | 
				
			||||||
@ -393,7 +416,7 @@ static struct wl_list clients; /* tiling order */
 | 
				
			|||||||
static struct wl_list fstack;  /* focus order */
 | 
					static struct wl_list fstack;  /* focus order */
 | 
				
			||||||
static struct wl_list stack;   /* stacking z-order */
 | 
					static struct wl_list stack;   /* stacking z-order */
 | 
				
			||||||
static struct wl_list independents;
 | 
					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_idle *idle;
 | 
				
			||||||
static struct wlr_layer_shell_v1 *layer_shell;
 | 
					static struct wlr_layer_shell_v1 *layer_shell;
 | 
				
			||||||
static struct wlr_output_manager_v1 *output_mgr;
 | 
					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_xcursor_manager *cursor_mgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_seat *seat;
 | 
					static struct wlr_seat *seat;
 | 
				
			||||||
struct wlr_input_method_manager_v2 *input_method_manager;
 | 
					struct wlr_input_method_manager_v2 *input_method_mgr;
 | 
				
			||||||
struct wlr_text_input_manager_v3 *text_input_manager;
 | 
					struct wlr_text_input_manager_v3 *text_input_mgr;
 | 
				
			||||||
struct dwl_input_method_relay *input_relay;
 | 
					InputMethodRelay *input_relay;
 | 
				
			||||||
static struct wl_list keyboards;
 | 
					static struct wl_list keyboards;
 | 
				
			||||||
static unsigned int cursor_mode;
 | 
					static unsigned int cursor_mode;
 | 
				
			||||||
static Client *grabc;
 | 
					static Client *grabc;
 | 
				
			||||||
@ -1203,7 +1226,7 @@ focusclient(Client *c, int lift)
 | 
				
			|||||||
	kb = wlr_seat_get_keyboard(seat);
 | 
						kb = wlr_seat_get_keyboard(seat);
 | 
				
			||||||
	wlr_seat_keyboard_notify_enter(seat, client_surface(c),
 | 
						wlr_seat_keyboard_notify_enter(seat, client_surface(c),
 | 
				
			||||||
			kb->keycodes, kb->num_keycodes, &kb->modifiers);
 | 
								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 */
 | 
						/* Activate the new client */
 | 
				
			||||||
	client_activate_surface(client_surface(c), 1);
 | 
						client_activate_surface(client_surface(c), 1);
 | 
				
			||||||
@ -1444,8 +1467,10 @@ mapnotify(struct wl_listener *listener, void *data)
 | 
				
			|||||||
	applyrules(c);
 | 
						applyrules(c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
 | 
					void
 | 
				
			||||||
	struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
 | 
					inputmethodgrabkeyboard(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						InputMethodRelay *relay = wl_container_of(listener, relay,
 | 
				
			||||||
		input_method_grab_keyboard);
 | 
							input_method_grab_keyboard);
 | 
				
			||||||
	struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
 | 
						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,
 | 
						wl_signal_add(&keyboard_grab->events.destroy,
 | 
				
			||||||
		&relay->input_method_keyboard_grab_destroy);
 | 
							&relay->input_method_keyboard_grab_destroy);
 | 
				
			||||||
	relay->input_method_keyboard_grab_destroy.notify =
 | 
						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) {
 | 
					void
 | 
				
			||||||
	struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
 | 
					inputmethodkeyboardgrabdestroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						InputMethodRelay *relay = wl_container_of(listener, relay,
 | 
				
			||||||
		input_method_keyboard_grab_destroy);
 | 
							input_method_keyboard_grab_destroy);
 | 
				
			||||||
	struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
 | 
						struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
 | 
				
			||||||
	wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
 | 
						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,
 | 
					render_input_popups(struct wlr_output* output, struct wl_list *input_popups,
 | 
				
			||||||
		struct timespec *now)
 | 
							struct timespec *now)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dwl_input_popup *popup;
 | 
						InputPopup *popup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_for_each(popup, input_popups, view_link) {
 | 
						wl_list_for_each(popup, input_popups, view_link) {
 | 
				
			||||||
		struct render_data rdata = {
 | 
							struct render_data rdata = {
 | 
				
			||||||
@ -2157,9 +2184,10 @@ setsel(struct wl_listener *listener, void *data)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// text-input-, and input_method-relevant functions
 | 
					// text-input-, and input_method-relevant functions
 | 
				
			||||||
static struct dwl_text_input *relay_get_focusable_text_input(
 | 
					TextInput *
 | 
				
			||||||
		struct dwl_input_method_relay *relay) {
 | 
					relaygetfocusabletextinput(InputMethodRelay *relay)
 | 
				
			||||||
	struct dwl_text_input *text_input = NULL;
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input = NULL;
 | 
				
			||||||
	wl_list_for_each(text_input, &relay->text_inputs, link) {
 | 
						wl_list_for_each(text_input, &relay->text_inputs, link) {
 | 
				
			||||||
		if (text_input->pending_focused_surface) {
 | 
							if (text_input->pending_focused_surface) {
 | 
				
			||||||
			return text_input;
 | 
								return text_input;
 | 
				
			||||||
@ -2168,9 +2196,10 @@ static struct dwl_text_input *relay_get_focusable_text_input(
 | 
				
			|||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct dwl_text_input *relay_get_focused_text_input(
 | 
					TextInput *
 | 
				
			||||||
		struct dwl_input_method_relay *relay) {
 | 
					relaygetfocusedtextinput(InputMethodRelay *relay)
 | 
				
			||||||
	struct dwl_text_input *text_input = NULL;
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input = NULL;
 | 
				
			||||||
	wl_list_for_each(text_input, &relay->text_inputs, link) {
 | 
						wl_list_for_each(text_input, &relay->text_inputs, link) {
 | 
				
			||||||
		if (text_input->input->focused_surface) {
 | 
							if (text_input->input->focused_surface) {
 | 
				
			||||||
			return text_input;
 | 
								return text_input;
 | 
				
			||||||
@ -2179,13 +2208,15 @@ static struct dwl_text_input *relay_get_focused_text_input(
 | 
				
			|||||||
	return NULL;
 | 
						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 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);
 | 
							input_method_commit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct dwl_text_input *text_input = relay_get_focused_text_input(relay);
 | 
						TextInput *text_input = relaygetfocusedtextinput(relay);
 | 
				
			||||||
	if (!text_input) {
 | 
						if (!text_input) {
 | 
				
			||||||
		return;
 | 
							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);
 | 
						wlr_text_input_v3_send_done(text_input->input);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void text_input_set_pending_focused_surface(
 | 
					void
 | 
				
			||||||
		struct dwl_text_input *text_input, struct wlr_surface *surface) {
 | 
					textinputsetpendingfocusedsurface(
 | 
				
			||||||
 | 
							TextInput *text_input, struct wlr_surface *surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	wl_list_remove(&text_input->pending_focused_surface_destroy.link);
 | 
						wl_list_remove(&text_input->pending_focused_surface_destroy.link);
 | 
				
			||||||
	text_input->pending_focused_surface = surface;
 | 
						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) {
 | 
					void
 | 
				
			||||||
	struct dwl_text_input *text_input;
 | 
					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);
 | 
							input_method_destroy);
 | 
				
			||||||
	struct wlr_input_method_v2 *context = data;
 | 
						struct wlr_input_method_v2 *context = data;
 | 
				
			||||||
	assert(context == relay->input_method);
 | 
						assert(context == relay->input_method);
 | 
				
			||||||
	relay->input_method = NULL;
 | 
						relay->input_method = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	text_input = relay_get_focused_text_input(relay);
 | 
						text_input = relaygetfocusedtextinput(relay);
 | 
				
			||||||
	if (text_input) {
 | 
						if (text_input) {
 | 
				
			||||||
		// keyboard focus is still there, so keep the surface at hand in case
 | 
							// keyboard focus is still there, so keep the surface at hand in case
 | 
				
			||||||
		// the input method returns
 | 
							// the input method returns
 | 
				
			||||||
		text_input_set_pending_focused_surface(text_input,
 | 
							textinputsetpendingfocusedsurface(text_input,
 | 
				
			||||||
			text_input->input->focused_surface);
 | 
								text_input->input->focused_surface);
 | 
				
			||||||
		wlr_text_input_v3_send_leave(text_input->input);
 | 
							wlr_text_input_v3_send_leave(text_input->input);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void relay_send_im_state(struct dwl_input_method_relay *relay,
 | 
					void
 | 
				
			||||||
		struct wlr_text_input_v3 *input) {
 | 
					relaysendinputmethodstate(InputMethodRelay *relay,
 | 
				
			||||||
 | 
							struct wlr_text_input_v3 *input)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	struct wlr_input_method_v2 *input_method = relay->input_method;
 | 
						struct wlr_input_method_v2 *input_method = relay->input_method;
 | 
				
			||||||
	if (!input_method) {
 | 
						if (!input_method) {
 | 
				
			||||||
		wlr_log(WLR_INFO, "Sending IM_DONE but im is gone");
 | 
							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
 | 
						// TODO: pass intent, display popup size
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_text_input_enable(struct wl_listener *listener, void *data) {
 | 
					void
 | 
				
			||||||
	struct dwl_text_input *text_input = wl_container_of(listener, text_input,
 | 
					textinputenable(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input = wl_container_of(listener, text_input,
 | 
				
			||||||
		text_input_enable);
 | 
							text_input_enable);
 | 
				
			||||||
	if (text_input->relay->input_method == NULL) {
 | 
						if (text_input->relay->input_method == NULL) {
 | 
				
			||||||
		wlr_log(WLR_INFO, "Enabling text input when input method is gone");
 | 
							wlr_log(WLR_INFO, "Enabling text input when input method is gone");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wlr_input_method_v2_send_activate(text_input->relay->input_method);
 | 
						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
 | 
				
			||||||
		void *data) {
 | 
					textinputcommit(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_text_input *text_input = wl_container_of(listener, text_input,
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input = wl_container_of(listener, text_input,
 | 
				
			||||||
		text_input_commit);
 | 
							text_input_commit);
 | 
				
			||||||
	if (!text_input->input->current_enabled) {
 | 
						if (!text_input->input->current_enabled) {
 | 
				
			||||||
		wlr_log(WLR_INFO, "Inactive text input tried to commit an update");
 | 
							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");
 | 
							wlr_log(WLR_INFO, "Text input committed, but input method is gone");
 | 
				
			||||||
		return;
 | 
							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,
 | 
					void
 | 
				
			||||||
		struct dwl_text_input *text_input) {
 | 
					relaydisabletextinput(InputMethodRelay *relay, TextInput *text_input)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	if (relay->input_method == NULL) {
 | 
						if (relay->input_method == NULL) {
 | 
				
			||||||
		wlr_log(WLR_DEBUG, "Disabling text input, but input method is gone");
 | 
							wlr_log(WLR_DEBUG, "Disabling text input, but input method is gone");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wlr_input_method_v2_send_deactivate(relay->input_method);
 | 
						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
 | 
				
			||||||
		void *data) {
 | 
					textinputdisable(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_text_input *text_input = wl_container_of(listener, text_input,
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input = wl_container_of(listener, text_input,
 | 
				
			||||||
		text_input_disable);
 | 
							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
 | 
				
			||||||
		void *data) {
 | 
					textinputdestroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_text_input *text_input = wl_container_of(listener, text_input,
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input = wl_container_of(listener, text_input,
 | 
				
			||||||
		text_input_destroy);
 | 
							text_input_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (text_input->input->current_enabled) {
 | 
						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_commit.link);
 | 
				
			||||||
	wl_list_remove(&text_input->text_input_destroy.link);
 | 
						wl_list_remove(&text_input->text_input_destroy.link);
 | 
				
			||||||
	wl_list_remove(&text_input->text_input_disable.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);
 | 
						free(text_input);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
 | 
					void
 | 
				
			||||||
		void *data) {
 | 
					destroypendingfocusedsurface(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_text_input *text_input = wl_container_of(listener, text_input,
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input = wl_container_of(listener, text_input,
 | 
				
			||||||
		pending_focused_surface_destroy);
 | 
							pending_focused_surface_destroy);
 | 
				
			||||||
	struct wlr_surface *surface = data;
 | 
						struct wlr_surface *surface = data;
 | 
				
			||||||
	assert(text_input->pending_focused_surface == surface);
 | 
						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);
 | 
						wl_list_init(&text_input->pending_focused_surface_destroy.link);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dwl_text_input *dwl_text_input_create(
 | 
					TextInput *
 | 
				
			||||||
		struct dwl_input_method_relay *relay,
 | 
					textinputcreate(InputMethodRelay *relay, struct wlr_text_input_v3 *text_input)
 | 
				
			||||||
		struct wlr_text_input_v3 *text_input) {
 | 
					{
 | 
				
			||||||
	struct dwl_text_input *input;
 | 
						TextInput *input;
 | 
				
			||||||
	input = calloc(1, sizeof(*input));
 | 
						input = calloc(1, sizeof(*input));
 | 
				
			||||||
	if (!input) {
 | 
						if (!input) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
@ -2347,53 +2391,45 @@ struct dwl_text_input *dwl_text_input_create(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	wl_list_insert(&relay->text_inputs, &input->link);
 | 
						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);
 | 
						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);
 | 
						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);
 | 
						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);
 | 
						wl_signal_add(&text_input->events.destroy, &input->text_input_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input->pending_focused_surface_destroy.notify =
 | 
						input->pending_focused_surface_destroy.notify =
 | 
				
			||||||
		handle_pending_focused_surface_destroy;
 | 
							destroypendingfocusedsurface;
 | 
				
			||||||
	wl_list_init(&input->pending_focused_surface_destroy.link);
 | 
						wl_list_init(&input->pending_focused_surface_destroy.link);
 | 
				
			||||||
	return input;
 | 
						return input;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void relay_handle_text_input(struct wl_listener *listener,
 | 
					void
 | 
				
			||||||
		void *data) {
 | 
					relaycreatetextinput(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
 | 
					{
 | 
				
			||||||
 | 
						InputMethodRelay *relay = wl_container_of(listener, relay,
 | 
				
			||||||
		text_input_new);
 | 
							text_input_new);
 | 
				
			||||||
	struct wlr_text_input_v3 *wlr_text_input = data;
 | 
						struct wlr_text_input_v3 *wlr_text_input = data;
 | 
				
			||||||
	if (seat != wlr_text_input->seat) {
 | 
						if (seat != wlr_text_input->seat) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dwl_text_input_create(relay, wlr_text_input);
 | 
						textinputcreate(relay, wlr_text_input);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static LayerSurface* layer_surface_from_wlr_layer_surface_v1(
 | 
					void
 | 
				
			||||||
		struct wlr_layer_surface_v1* layer_surface) {
 | 
					inputpopupsendoutputs(InputPopup *popup, wlr_surface_iterator_func_t iterator)
 | 
				
			||||||
	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) {
 | 
					 | 
				
			||||||
	struct wlr_surface* focused_surface;
 | 
						struct wlr_surface* focused_surface;
 | 
				
			||||||
	struct wlr_output* output;
 | 
						struct wlr_output* output;
 | 
				
			||||||
	Client* client;
 | 
						Client* client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct dwl_text_input *text_input =
 | 
						TextInput *text_input = relaygetfocusedtextinput(popup->relay);
 | 
				
			||||||
		relay_get_focused_text_input(popup->relay);
 | 
					 | 
				
			||||||
	if (!text_input || !text_input->input->focused_surface) {
 | 
						if (!text_input || !text_input->input->focused_surface) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -2407,41 +2443,44 @@ static void input_popup_send_outputs(struct dwl_input_popup *popup,
 | 
				
			|||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	client = client_from_wlr_surface(focused_surface);
 | 
						client = focused_surface->data;
 | 
				
			||||||
	output = client->mon->wlr_output;
 | 
						output = client->mon->wlr_output;
 | 
				
			||||||
	wlr_surface_for_each_surface(popup->popup_surface->surface,
 | 
						wlr_surface_for_each_surface(popup->popup_surface->surface,
 | 
				
			||||||
		iterator, output);
 | 
							iterator, output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void surface_send_enter_iterator(struct wlr_surface *surface,
 | 
					void
 | 
				
			||||||
		int x, int y, void *data) {
 | 
					surfacesendenter(struct wlr_surface *surface, int x, int y, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	struct wlr_output *wlr_output = data;
 | 
						struct wlr_output *wlr_output = data;
 | 
				
			||||||
	wlr_surface_send_enter(surface, wlr_output);
 | 
						wlr_surface_send_enter(surface, wlr_output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void surface_send_leave_iterator(struct wlr_surface *surface,
 | 
					void
 | 
				
			||||||
		int x, int y, void *data) {
 | 
					surfacesendleave(struct wlr_surface *surface, int x, int y, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	struct wlr_output *wlr_output = data;
 | 
						struct wlr_output *wlr_output = data;
 | 
				
			||||||
	wlr_surface_send_leave(surface, wlr_output);
 | 
						wlr_surface_send_leave(surface, wlr_output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void get_parent_and_output_box(struct wlr_surface *focused_surface,
 | 
					void
 | 
				
			||||||
		struct wlr_box *parent, struct wlr_box *output_box) {
 | 
					getparentandoutputbox(struct wlr_surface *focused_surface,
 | 
				
			||||||
 | 
							struct wlr_box *parent, struct wlr_box *output_box)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	struct wlr_output *output;
 | 
						struct wlr_output *output;
 | 
				
			||||||
	struct wlr_box *output_box_tmp;
 | 
						struct wlr_box *output_box_tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wlr_surface_is_layer_surface(focused_surface)) {
 | 
						if (wlr_surface_is_layer_surface(focused_surface)) {
 | 
				
			||||||
		struct wlr_layer_surface_v1 *layer_surface =
 | 
							struct wlr_layer_surface_v1 *layer_surface =
 | 
				
			||||||
			wlr_layer_surface_v1_from_wlr_surface(focused_surface);
 | 
								wlr_layer_surface_v1_from_wlr_surface(focused_surface);
 | 
				
			||||||
		LayerSurface* layer =
 | 
							LayerSurface* layer = layer_surface->data;
 | 
				
			||||||
			layer_surface_from_wlr_layer_surface_v1(layer_surface);
 | 
					 | 
				
			||||||
		output = layer->layer_surface->output;
 | 
							output = layer->layer_surface->output;
 | 
				
			||||||
		output_box_tmp = wlr_output_layout_get_box(output_layout, output);
 | 
							output_box_tmp = wlr_output_layout_get_box(output_layout, output);
 | 
				
			||||||
		*parent = layer->geo;
 | 
							*parent = layer->geo;
 | 
				
			||||||
		parent->x += output_box_tmp->x;
 | 
							parent->x += output_box_tmp->x;
 | 
				
			||||||
		parent->y += output_box_tmp->y;
 | 
							parent->y += output_box_tmp->y;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		Client *client = client_from_wlr_surface(focused_surface);
 | 
							Client *client = focused_surface->data;
 | 
				
			||||||
		output = wlr_output_layout_output_at(output_layout,
 | 
							output = wlr_output_layout_output_at(output_layout,
 | 
				
			||||||
			client->geom.x, client->geom.y);
 | 
								client->geom.x, client->geom.y);
 | 
				
			||||||
		output_box_tmp = wlr_output_layout_get_box(output_layout, output);
 | 
							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;
 | 
						*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_surface* focused_surface;
 | 
				
			||||||
	struct wlr_box output_box, parent, cursor;
 | 
						struct wlr_box output_box, parent, cursor;
 | 
				
			||||||
	int x1, x2, y1, y2, x, y, available_right, available_left, available_down,
 | 
						int x1, x2, y1, y2, x, y, available_right, available_left, available_down,
 | 
				
			||||||
			available_up, popup_width, popup_height;
 | 
								available_up, popup_width, popup_height;
 | 
				
			||||||
	bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds;
 | 
						bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct dwl_text_input *text_input =
 | 
						TextInput *text_input =
 | 
				
			||||||
		relay_get_focused_text_input(popup->relay);
 | 
							relaygetfocusedtextinput(popup->relay);
 | 
				
			||||||
	if (!text_input|| !text_input->input->focused_surface) {
 | 
						if (!text_input|| !text_input->input->focused_surface) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -2476,7 +2517,7 @@ static void input_popup_update(struct dwl_input_popup *popup) {
 | 
				
			|||||||
	focused_surface = text_input->input->focused_surface;
 | 
						focused_surface = text_input->input->focused_surface;
 | 
				
			||||||
	cursor = text_input->input->current.cursor_rectangle;
 | 
						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) {
 | 
						if (!cursor_rect) {
 | 
				
			||||||
		cursor.x = 0;
 | 
							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) {
 | 
					void
 | 
				
			||||||
	struct dwl_input_popup *popup =
 | 
					inputmethodpopupmap(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						InputPopup *popup =
 | 
				
			||||||
		wl_container_of(listener, popup, popup_map);
 | 
							wl_container_of(listener, popup, popup_map);
 | 
				
			||||||
	input_popup_send_outputs(popup, surface_send_enter_iterator);
 | 
						inputpopupsendoutputs(popup, surfacesendenter);
 | 
				
			||||||
	input_popup_update(popup);
 | 
						updateinputpopup(popup);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_im_popup_unmap(struct wl_listener *listener, void *data) {
 | 
					void
 | 
				
			||||||
	struct dwl_input_popup *popup =
 | 
					inputmethodpopupunmap(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						InputPopup *popup =
 | 
				
			||||||
		wl_container_of(listener, popup, popup_unmap);
 | 
							wl_container_of(listener, popup, popup_unmap);
 | 
				
			||||||
	input_popup_send_outputs(popup, surface_send_leave_iterator);
 | 
						inputpopupsendoutputs(popup, surfacesendleave);
 | 
				
			||||||
	input_popup_update(popup);
 | 
						updateinputpopup(popup);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_im_popup_destroy(struct wl_listener *listener, void *data) {
 | 
					void
 | 
				
			||||||
	struct dwl_input_popup *popup =
 | 
					inputmethodpopupdestroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						InputPopup *popup =
 | 
				
			||||||
		wl_container_of(listener, popup, popup_destroy);
 | 
							wl_container_of(listener, popup, popup_destroy);
 | 
				
			||||||
	wl_list_remove(&popup->focused_surface_unmap.link);
 | 
						wl_list_remove(&popup->focused_surface_unmap.link);
 | 
				
			||||||
	wl_list_remove(&popup->popup_surface_commit.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);
 | 
						free(popup);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_im_popup_surface_commit(struct wl_listener *listener,
 | 
					void
 | 
				
			||||||
		void *data) {
 | 
					inputmethodpopupsurfacecommit(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_input_popup *popup =
 | 
					{
 | 
				
			||||||
 | 
						InputPopup *popup =
 | 
				
			||||||
		wl_container_of(listener, popup, popup_surface_commit);
 | 
							wl_container_of(listener, popup, popup_surface_commit);
 | 
				
			||||||
	input_popup_update(popup);
 | 
						updateinputpopup(popup);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_im_focused_surface_destroy(
 | 
					void
 | 
				
			||||||
		struct wl_listener *listener, void *data) {
 | 
					inputmethodfocusedsurfacedestroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_input_popup *popup =
 | 
					{
 | 
				
			||||||
 | 
						InputPopup *popup =
 | 
				
			||||||
		wl_container_of(listener, popup, focused_surface_unmap);
 | 
							wl_container_of(listener, popup, focused_surface_unmap);
 | 
				
			||||||
	wl_list_remove(&popup->view_link);
 | 
						wl_list_remove(&popup->view_link);
 | 
				
			||||||
	wl_list_init(&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,
 | 
					void
 | 
				
			||||||
		struct wlr_surface *surface) {
 | 
					inputpopupsetfocus(InputPopup *popup, struct wlr_surface *surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	Client* client;
 | 
						Client* client;
 | 
				
			||||||
	struct wlr_layer_surface_v1* layer_surface;
 | 
						struct wlr_layer_surface_v1* layer_surface;
 | 
				
			||||||
	LayerSurface* layer;
 | 
						LayerSurface* layer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!surface)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&popup->view_link);
 | 
						wl_list_remove(&popup->view_link);
 | 
				
			||||||
	wl_list_remove(&popup->focused_surface_unmap.link);
 | 
						wl_list_remove(&popup->focused_surface_unmap.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wlr_surface_is_layer_surface(surface)) {
 | 
						if (wlr_surface_is_layer_surface(surface)) {
 | 
				
			||||||
		layer_surface = wlr_layer_surface_v1_from_wlr_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_list_insert(&input_popups, &popup->view_link);
 | 
				
			||||||
		wl_signal_add(&layer->layer_surface->events.unmap,
 | 
							wl_signal_add(&layer->layer_surface->events.unmap,
 | 
				
			||||||
				&popup->focused_surface_unmap);
 | 
									&popup->focused_surface_unmap);
 | 
				
			||||||
		input_popup_update(popup);
 | 
							updateinputpopup(popup);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	client = client_from_wlr_surface(surface);
 | 
						client = surface->data;
 | 
				
			||||||
	wl_list_insert(&input_popups, &popup->view_link);
 | 
						wl_list_insert(&input_popups, &popup->view_link);
 | 
				
			||||||
	wl_signal_add(&client->surface.xdg->events.unmap,
 | 
						wl_signal_add(&client->surface.xdg->events.unmap,
 | 
				
			||||||
			&popup->focused_surface_unmap);
 | 
								&popup->focused_surface_unmap);
 | 
				
			||||||
	input_popup_update(popup);
 | 
						updateinputpopup(popup);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_im_new_popup_surface(struct wl_listener *listener, void *data) {
 | 
					void
 | 
				
			||||||
	struct dwl_text_input* text_input;
 | 
					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);
 | 
							input_method_new_popup_surface);
 | 
				
			||||||
	struct dwl_input_popup *popup = calloc(1, sizeof(*popup));
 | 
						InputPopup *popup = calloc(1, sizeof(*popup));
 | 
				
			||||||
	popup->relay = relay;
 | 
						popup->relay = relay;
 | 
				
			||||||
	popup->popup_surface = data;
 | 
						popup->popup_surface = data;
 | 
				
			||||||
	popup->popup_surface->data = popup;
 | 
						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_list_init(&popup->view_link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_add(&popup->popup_surface->events.map, &popup->popup_map);
 | 
						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(
 | 
						wl_signal_add(
 | 
				
			||||||
		&popup->popup_surface->events.unmap, &popup->popup_unmap);
 | 
							&popup->popup_surface->events.unmap, &popup->popup_unmap);
 | 
				
			||||||
	popup->popup_unmap.notify = handle_im_popup_unmap;
 | 
						popup->popup_unmap.notify = inputmethodpopupunmap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_add(
 | 
						wl_signal_add(
 | 
				
			||||||
		&popup->popup_surface->events.destroy, &popup->popup_destroy);
 | 
							&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,
 | 
						wl_signal_add(&popup->popup_surface->surface->events.commit,
 | 
				
			||||||
		&popup->popup_surface_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);
 | 
						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) {
 | 
						if (text_input) {
 | 
				
			||||||
		input_popup_set_focus(popup, text_input->input->focused_surface);
 | 
							inputpopupsetfocus(popup, text_input->input->focused_surface);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		input_popup_set_focus(popup, NULL);
 | 
							inputpopupsetfocus(popup, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_insert(&relay->input_popups, &popup->link);
 | 
						wl_list_insert(&relay->input_popups, &popup->link);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void relay_handle_input_method(struct wl_listener *listener,
 | 
					void
 | 
				
			||||||
		void *data) {
 | 
					relaycreateinputmethod(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct dwl_text_input *text_input;
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
 | 
						InputMethodRelay *relay = wl_container_of(listener, relay,
 | 
				
			||||||
		input_method_new);
 | 
							input_method_new);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_input_method_v2 *input_method = data;
 | 
						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;
 | 
						relay->input_method = input_method;
 | 
				
			||||||
	wl_signal_add(&relay->input_method->events.commit,
 | 
						wl_signal_add(&relay->input_method->events.commit,
 | 
				
			||||||
		&relay->input_method_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,
 | 
						wl_signal_add(&relay->input_method->events.new_popup_surface,
 | 
				
			||||||
		&relay->input_method_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,
 | 
						wl_signal_add(&relay->input_method->events.grab_keyboard,
 | 
				
			||||||
		&relay->input_method_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,
 | 
						wl_signal_add(&relay->input_method->events.destroy,
 | 
				
			||||||
		&relay->input_method_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) {
 | 
						if (text_input) {
 | 
				
			||||||
		wlr_text_input_v3_send_enter(text_input->input,
 | 
							wlr_text_input_v3_send_enter(text_input->input,
 | 
				
			||||||
			text_input->pending_focused_surface);
 | 
								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) {
 | 
					void
 | 
				
			||||||
	wl_list_init(&relay->text_inputs);
 | 
					inputmethodrelaysetfocus(InputMethodRelay *relay, struct wlr_surface *surface)
 | 
				
			||||||
	wl_list_init(&relay->input_popups);
 | 
					{
 | 
				
			||||||
 | 
						TextInput *text_input;
 | 
				
			||||||
	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;
 | 
					 | 
				
			||||||
	wl_list_for_each(text_input, &relay->text_inputs, link) {
 | 
						wl_list_for_each(text_input, &relay->text_inputs, link) {
 | 
				
			||||||
		if (text_input->pending_focused_surface) {
 | 
							if (text_input->pending_focused_surface) {
 | 
				
			||||||
			assert(text_input->input->focused_surface == NULL);
 | 
								assert(text_input->input->focused_surface == NULL);
 | 
				
			||||||
			if (surface != text_input->pending_focused_surface) {
 | 
								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) {
 | 
							} else if (text_input->input->focused_surface) {
 | 
				
			||||||
			assert(text_input->pending_focused_surface == NULL);
 | 
								assert(text_input->pending_focused_surface == NULL);
 | 
				
			||||||
			if (surface != text_input->input->focused_surface) {
 | 
								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);
 | 
									wlr_text_input_v3_send_leave(text_input->input);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				wlr_log(WLR_DEBUG, "IM relay set_focus already focused");
 | 
									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) {
 | 
								if (relay->input_method) {
 | 
				
			||||||
				wlr_text_input_v3_send_enter(text_input->input, surface);
 | 
									wlr_text_input_v3_send_enter(text_input->input, surface);
 | 
				
			||||||
			} else {
 | 
								} 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);
 | 
						presentation = wlr_presentation_create(dpy, backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* create text_input-, and input_method-protocol relevant globals */
 | 
						/* create text_input-, and input_method-protocol relevant globals */
 | 
				
			||||||
	input_method_manager = wlr_input_method_manager_v2_create(dpy);
 | 
						input_method_mgr = wlr_input_method_manager_v2_create(dpy);
 | 
				
			||||||
	text_input_manager = wlr_text_input_manager_v3_create(dpy);
 | 
						text_input_mgr = wlr_text_input_manager_v3_create(dpy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input_relay = calloc(1, sizeof(*input_relay));
 | 
						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
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user