give types some more dwm-like typedef names
This commit is contained in:
		
							
								
								
									
										306
									
								
								dwl.c
									
									
									
									
									
								
							
							
						
						
									
										306
									
								
								dwl.c
									
									
									
									
									
								
							| @@ -35,13 +35,21 @@ | ||||
| /* enums */ | ||||
| enum { CurNormal, CurMove, CurResize }; /* cursor */ | ||||
|  | ||||
| struct dwl_output { | ||||
| 	struct wl_list link; | ||||
| 	struct wlr_output *wlr_output; | ||||
| 	struct wl_listener frame; | ||||
| }; | ||||
| typedef union { | ||||
| 	int i; | ||||
| 	unsigned int ui; | ||||
| 	float f; | ||||
| 	const void *v; | ||||
| } Arg; | ||||
|  | ||||
| struct dwl_view { | ||||
| typedef struct { | ||||
| 	unsigned int mod; | ||||
| 	unsigned int button; | ||||
| 	void (*func)(const Arg *); | ||||
| 	const Arg arg; | ||||
| } Button; | ||||
|  | ||||
| typedef struct { | ||||
| 	struct wl_list link; | ||||
| 	struct wlr_xdg_surface *xdg_surface; | ||||
| 	struct wl_listener map; | ||||
| @@ -51,22 +59,7 @@ struct dwl_view { | ||||
| 	struct wl_listener request_resize; | ||||
| 	bool mapped; | ||||
| 	int x, y; | ||||
| }; | ||||
|  | ||||
| struct dwl_keyboard { | ||||
| 	struct wl_list link; | ||||
| 	struct wlr_input_device *device; | ||||
|  | ||||
| 	struct wl_listener modifiers; | ||||
| 	struct wl_listener key; | ||||
| }; | ||||
|  | ||||
| typedef union { | ||||
| 	int i; | ||||
| 	unsigned int ui; | ||||
| 	float f; | ||||
| 	const void *v; | ||||
| } Arg; | ||||
| } Client; | ||||
|  | ||||
| typedef struct { | ||||
| 	uint32_t mod; | ||||
| @@ -76,22 +69,37 @@ typedef struct { | ||||
| } Key; | ||||
|  | ||||
| typedef struct { | ||||
| 	unsigned int mod; | ||||
| 	unsigned int button; | ||||
| 	void (*func)(const Arg *); | ||||
| 	const Arg arg; | ||||
| } Button; | ||||
| 	struct wl_list link; | ||||
| 	struct wlr_input_device *device; | ||||
|  | ||||
| 	struct wl_listener modifiers; | ||||
| 	struct wl_listener key; | ||||
| } Keyboard; | ||||
|  | ||||
| typedef struct { | ||||
| 	struct wl_list link; | ||||
| 	struct wlr_output *wlr_output; | ||||
| 	struct wl_listener frame; | ||||
| } Monitor; | ||||
|  | ||||
| /* Used to move all of the data necessary to render a surface from the top-level | ||||
|  * frame handler to the per-surface render function. */ | ||||
| struct render_data { | ||||
| 	struct wlr_output *output; | ||||
| 	Client *client; | ||||
| 	struct timespec *when; | ||||
| }; | ||||
|  | ||||
| /* function declarations */ | ||||
| static void axisnotify(struct wl_listener *listener, void *data); | ||||
| static void buttonpress(struct wl_listener *listener, void *data); | ||||
| static void createkeyboard(struct wlr_input_device *device); | ||||
| static void createnotify(struct wl_listener *listener, void *data); | ||||
| static void createoutput(struct wl_listener *listener, void *data); | ||||
| static void createmon(struct wl_listener *listener, void *data); | ||||
| static void createpointer(struct wlr_input_device *device); | ||||
| static void cursorframe(struct wl_listener *listener, void *data); | ||||
| static void destroynotify(struct wl_listener *listener, void *data); | ||||
| static void focus(struct dwl_view *view, struct wlr_surface *surface); | ||||
| static void focus(Client *c, struct wlr_surface *surface); | ||||
| static void focusnext(const Arg *arg); | ||||
| static void handlemove(uint32_t time); | ||||
| static void handleresize(uint32_t time); | ||||
| @@ -104,17 +112,17 @@ static void motionabsolute(struct wl_listener *listener, void *data); | ||||
| static void motionnotify(uint32_t time); | ||||
| static void motionrelative(struct wl_listener *listener, void *data); | ||||
| static void movemouse(const Arg *arg); | ||||
| static void moveresize(struct dwl_view *view, unsigned int mode); | ||||
| static void moveresize(Client *c, unsigned int mode); | ||||
| static void quit(const Arg *arg); | ||||
| static void render(struct wlr_surface *surface, int sx, int sy, void *data); | ||||
| static void renderoutput(struct wl_listener *listener, void *data); | ||||
| static void rendermon(struct wl_listener *listener, void *data); | ||||
| static void resizemouse(const Arg *arg); | ||||
| static void setcursor(struct wl_listener *listener, void *data); | ||||
| static void spawn(const Arg *arg); | ||||
| static void unmapnotify(struct wl_listener *listener, void *data); | ||||
| static bool xytosurface(struct dwl_view *view, double lx, double ly, | ||||
| static bool xytosurface(Client *c, double lx, double ly, | ||||
| 		struct wlr_surface **surface, double *sx, double *sy); | ||||
| static struct dwl_view * xytoview(double lx, double ly, | ||||
| static Client * xytoclient(double lx, double ly, | ||||
| 		struct wlr_surface **surface, double *sx, double *sy); | ||||
|  | ||||
| /* variables */ | ||||
| @@ -124,7 +132,7 @@ static struct wlr_renderer *renderer; | ||||
|  | ||||
| static struct wlr_xdg_shell *xdg_shell; | ||||
| static struct wl_listener new_xdg_surface; | ||||
| static struct wl_list views; | ||||
| static struct wl_list clients; | ||||
|  | ||||
| static struct wlr_cursor *cursor; | ||||
| static struct wlr_xcursor_manager *cursor_mgr; | ||||
| @@ -139,24 +147,16 @@ static struct wl_listener new_input; | ||||
| static struct wl_listener request_cursor; | ||||
| static struct wl_list keyboards; | ||||
| static unsigned int cursor_mode; | ||||
| static struct dwl_view *grabbed_view; | ||||
| static Client *grabbed_client; | ||||
| static double grab_x, grab_y; | ||||
| static int grab_width, grab_height; | ||||
|  | ||||
| static struct wlr_output_layout *output_layout; | ||||
| static struct wl_list outputs; | ||||
| static struct wl_list mons; | ||||
| static struct wl_listener new_output; | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| /* Used to move all of the data necessary to render a surface from the top-level | ||||
|  * frame handler to the per-surface render function. */ | ||||
| struct render_data { | ||||
| 	struct wlr_output *output; | ||||
| 	struct dwl_view *view; | ||||
| 	struct timespec *when; | ||||
| }; | ||||
|  | ||||
| void | ||||
| axisnotify(struct wl_listener *listener, void *data) | ||||
| { | ||||
| @@ -180,14 +180,14 @@ buttonpress(struct wl_listener *listener, void *data) | ||||
| 			event->time_msec, event->button, event->state); | ||||
| 	double sx, sy; | ||||
| 	struct wlr_surface *surface; | ||||
| 	struct dwl_view *view = xytoview(cursor->x, cursor->y, | ||||
| 	Client *c = xytoclient(cursor->x, cursor->y, | ||||
| 			&surface, &sx, &sy); | ||||
| 	if (event->state == WLR_BUTTON_RELEASED) { | ||||
| 		/* If you released any buttons, we exit interactive move/resize mode. */ | ||||
| 		cursor_mode = CurNormal; | ||||
| 	} else { | ||||
| 		/* Focus that client if the button was _pressed_ */ | ||||
| 		focus(view, surface); | ||||
| 		focus(c, surface); | ||||
|  | ||||
| 		struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat); | ||||
| 		uint32_t mods = wlr_keyboard_get_modifiers(keyboard); | ||||
| @@ -204,7 +204,7 @@ buttonpress(struct wl_listener *listener, void *data) | ||||
| void | ||||
| createkeyboard(struct wlr_input_device *device) | ||||
| { | ||||
| 	struct dwl_keyboard *keyboard = calloc(1, sizeof(*keyboard)); | ||||
| 	Keyboard *keyboard = calloc(1, sizeof(*keyboard)); | ||||
| 	keyboard->device = device; | ||||
|  | ||||
| 	/* We need to prepare an XKB keymap and assign it to the keyboard. This | ||||
| @@ -240,24 +240,24 @@ createnotify(struct wl_listener *listener, void *data) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* Allocate a dwl_view for this surface */ | ||||
| 	struct dwl_view *view = calloc(1, sizeof(*view)); | ||||
| 	view->xdg_surface = xdg_surface; | ||||
| 	/* Allocate a Client for this surface */ | ||||
| 	Client *c = calloc(1, sizeof(*c)); | ||||
| 	c->xdg_surface = xdg_surface; | ||||
|  | ||||
| 	/* Listen to the various events it can emit */ | ||||
| 	view->map.notify = maprequest; | ||||
| 	wl_signal_add(&xdg_surface->events.map, &view->map); | ||||
| 	view->unmap.notify = unmapnotify; | ||||
| 	wl_signal_add(&xdg_surface->events.unmap, &view->unmap); | ||||
| 	view->destroy.notify = destroynotify; | ||||
| 	wl_signal_add(&xdg_surface->events.destroy, &view->destroy); | ||||
| 	c->map.notify = maprequest; | ||||
| 	wl_signal_add(&xdg_surface->events.map, &c->map); | ||||
| 	c->unmap.notify = unmapnotify; | ||||
| 	wl_signal_add(&xdg_surface->events.unmap, &c->unmap); | ||||
| 	c->destroy.notify = destroynotify; | ||||
| 	wl_signal_add(&xdg_surface->events.destroy, &c->destroy); | ||||
|  | ||||
| 	/* Add it to the list of views. */ | ||||
| 	wl_list_insert(&views, &view->link); | ||||
| 	/* Add it to the list of clients. */ | ||||
| 	wl_list_insert(&clients, &c->link); | ||||
| } | ||||
|  | ||||
| void | ||||
| createoutput(struct wl_listener *listener, void *data) | ||||
| createmon(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	/* This event is rasied by the backend when a new output (aka a display or | ||||
| 	 * monitor) becomes available. */ | ||||
| @@ -278,12 +278,12 @@ createoutput(struct wl_listener *listener, void *data) | ||||
| 	} | ||||
|  | ||||
| 	/* Allocates and configures our state for this output */ | ||||
| 	struct dwl_output *output = calloc(1, sizeof(*output)); | ||||
| 	output->wlr_output = wlr_output; | ||||
| 	Monitor *m = calloc(1, sizeof(*m)); | ||||
| 	m->wlr_output = wlr_output; | ||||
| 	/* Sets up a listener for the frame notify event. */ | ||||
| 	output->frame.notify = renderoutput; | ||||
| 	wl_signal_add(&wlr_output->events.frame, &output->frame); | ||||
| 	wl_list_insert(&outputs, &output->link); | ||||
| 	m->frame.notify = rendermon; | ||||
| 	wl_signal_add(&wlr_output->events.frame, &m->frame); | ||||
| 	wl_list_insert(&mons, &m->link); | ||||
|  | ||||
| 	/* Adds this to the output layout. The add_auto function arranges outputs | ||||
| 	 * from left-to-right in the order they appear. A more sophisticated | ||||
| @@ -322,16 +322,16 @@ void | ||||
| destroynotify(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	/* Called when the surface is destroyed and should never be shown again. */ | ||||
| 	struct dwl_view *view = wl_container_of(listener, view, destroy); | ||||
| 	wl_list_remove(&view->link); | ||||
| 	free(view); | ||||
| 	Client *c = wl_container_of(listener, c, destroy); | ||||
| 	wl_list_remove(&c->link); | ||||
| 	free(c); | ||||
| } | ||||
|  | ||||
| void | ||||
| focus(struct dwl_view *view, struct wlr_surface *surface) | ||||
| focus(Client *c, struct wlr_surface *surface) | ||||
| { | ||||
| 	/* Note: this function only deals with keyboard focus. */ | ||||
| 	if (view == NULL) { | ||||
| 	if (c == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 	struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface; | ||||
| @@ -350,43 +350,41 @@ focus(struct dwl_view *view, struct wlr_surface *surface) | ||||
| 		wlr_xdg_toplevel_set_activated(previous, false); | ||||
| 	} | ||||
| 	struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat); | ||||
| 	/* Move the view to the front */ | ||||
| 	wl_list_remove(&view->link); | ||||
| 	wl_list_insert(&views, &view->link); | ||||
| 	/* Move the client to the front */ | ||||
| 	wl_list_remove(&c->link); | ||||
| 	wl_list_insert(&clients, &c->link); | ||||
| 	/* Activate the new surface */ | ||||
| 	wlr_xdg_toplevel_set_activated(view->xdg_surface, true); | ||||
| 	wlr_xdg_toplevel_set_activated(c->xdg_surface, true); | ||||
| 	/* | ||||
| 	 * Tell the seat to have the keyboard enter this surface. wlroots will keep | ||||
| 	 * track of this and automatically send key events to the appropriate | ||||
| 	 * clients without additional work on your part. | ||||
| 	 */ | ||||
| 	wlr_seat_keyboard_notify_enter(seat, view->xdg_surface->surface, | ||||
| 	wlr_seat_keyboard_notify_enter(seat, c->xdg_surface->surface, | ||||
| 		keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers); | ||||
| } | ||||
|  | ||||
| void | ||||
| focusnext(const Arg *arg) | ||||
| { | ||||
| 	/* Cycle to the next view */ | ||||
| 	if (wl_list_length(&views) < 2) { | ||||
| 	/* Cycle to the next client */ | ||||
| 	if (wl_list_length(&clients) < 2) { | ||||
| 		return; | ||||
| 	} | ||||
| 	struct dwl_view *current_view = wl_container_of( | ||||
| 		views.next, current_view, link); | ||||
| 	struct dwl_view *next_view = wl_container_of( | ||||
| 		current_view->link.next, next_view, link); | ||||
| 	focus(next_view, next_view->xdg_surface->surface); | ||||
| 	/* Move the previous view to the end of the list */ | ||||
| 	wl_list_remove(¤t_view->link); | ||||
| 	wl_list_insert(views.prev, ¤t_view->link); | ||||
| 	Client *c = wl_container_of(clients.next, c, link); | ||||
| 	Client *n = wl_container_of(c->link.next, n, link); | ||||
| 	focus(n, n->xdg_surface->surface); | ||||
| 	/* Move the previous client to the end of the list */ | ||||
| 	wl_list_remove(&c->link); | ||||
| 	wl_list_insert(clients.prev, &c->link); | ||||
| } | ||||
|  | ||||
| void | ||||
| handlemove(uint32_t time) | ||||
| { | ||||
| 	/* Move the grabbed view to the new position. */ | ||||
| 	grabbed_view->x = cursor->x - grab_x; | ||||
| 	grabbed_view->y = cursor->y - grab_y; | ||||
| 	/* Move the grabbed client to the new position. */ | ||||
| 	grabbed_client->x = cursor->x - grab_x; | ||||
| 	grabbed_client->y = cursor->y - grab_y; | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -399,7 +397,7 @@ handleresize(uint32_t time) | ||||
| 	 */ | ||||
| 	double dx = cursor->x - grab_x; | ||||
| 	double dy = cursor->y - grab_y; | ||||
| 	wlr_xdg_toplevel_set_size(grabbed_view->xdg_surface, | ||||
| 	wlr_xdg_toplevel_set_size(grabbed_client->xdg_surface, | ||||
| 			grab_width + dx, grab_height + dy); | ||||
| } | ||||
|  | ||||
| @@ -453,7 +451,7 @@ void | ||||
| keypress(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	/* This event is raised when a key is pressed or released. */ | ||||
| 	struct dwl_keyboard *keyboard = | ||||
| 	Keyboard *keyboard = | ||||
| 		wl_container_of(listener, keyboard, key); | ||||
| 	struct wlr_event_keyboard_key *event = data; | ||||
|  | ||||
| @@ -486,8 +484,7 @@ keypressmod(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	/* This event is raised when a modifier key, such as shift or alt, is | ||||
| 	 * pressed. We simply communicate this to the client. */ | ||||
| 	struct dwl_keyboard *keyboard = | ||||
| 		wl_container_of(listener, keyboard, modifiers); | ||||
| 	Keyboard *keyboard = wl_container_of(listener, keyboard, modifiers); | ||||
| 	/* | ||||
| 	 * A seat can only have one keyboard, but this is a limitation of the | ||||
| 	 * Wayland protocol - not wlroots. We assign all connected keyboards to the | ||||
| @@ -504,9 +501,9 @@ void | ||||
| maprequest(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	/* Called when the surface is mapped, or ready to display on-screen. */ | ||||
| 	struct dwl_view *view = wl_container_of(listener, view, map); | ||||
| 	view->mapped = true; | ||||
| 	focus(view, view->xdg_surface->surface); | ||||
| 	Client *c = wl_container_of(listener, c, map); | ||||
| 	c->mapped = true; | ||||
| 	focus(c, c->xdg_surface->surface); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -535,15 +532,15 @@ motionnotify(uint32_t time) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* Otherwise, find the view under the pointer and send the event along. */ | ||||
| 	/* Otherwise, find the client under the pointer and send the event along. */ | ||||
| 	double sx, sy; | ||||
| 	struct wlr_surface *surface = NULL; | ||||
| 	struct dwl_view *view = xytoview(cursor->x, cursor->y, | ||||
| 	Client *c = xytoclient(cursor->x, cursor->y, | ||||
| 			&surface, &sx, &sy); | ||||
| 	if (!view) { | ||||
| 		/* If there's no view under the cursor, set the cursor image to a | ||||
| 	if (!c) { | ||||
| 		/* If there's no client under the cursor, set the cursor image to a | ||||
| 		 * default. This is what makes the cursor image appear when you move it | ||||
| 		 * around the screen, not over any views. */ | ||||
| 		 * around the screen, not over any clients. */ | ||||
| 		wlr_xcursor_manager_set_cursor_image( | ||||
| 				cursor_mgr, "left_ptr", cursor); | ||||
| 	} | ||||
| @@ -591,33 +588,33 @@ movemouse(const Arg *arg) | ||||
| { | ||||
| 	double sx, sy; | ||||
| 	struct wlr_surface *surface; | ||||
| 	struct dwl_view *view = xytoview(cursor->x, cursor->y, | ||||
| 	Client *c = xytoclient(cursor->x, cursor->y, | ||||
| 			&surface, &sx, &sy); | ||||
| 	if (!view) { | ||||
| 	if (!c) { | ||||
| 		return; | ||||
| 	} | ||||
| 	moveresize(view, CurMove); | ||||
| 	moveresize(c, CurMove); | ||||
| } | ||||
|  | ||||
| void | ||||
| moveresize(struct dwl_view *view, unsigned int mode) | ||||
| moveresize(Client *c, unsigned int mode) | ||||
| { | ||||
| 	/* This function sets up an interactive move or resize operation, where the | ||||
| 	 * compositor stops propagating pointer events to clients and instead | ||||
| 	 * consumes them itself, to move or resize windows. */ | ||||
| 	struct wlr_surface *focused_surface = | ||||
| 		seat->pointer_state.focused_surface; | ||||
| 	if (view->xdg_surface->surface != focused_surface) { | ||||
| 	if (c->xdg_surface->surface != focused_surface) { | ||||
| 		/* Deny move/resize requests from unfocused clients. */ | ||||
| 		return; | ||||
| 	} | ||||
| 	grabbed_view = view; | ||||
| 	grabbed_client = c; | ||||
| 	cursor_mode = mode; | ||||
| 	struct wlr_box geo_box; | ||||
| 	wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box); | ||||
| 	wlr_xdg_surface_get_geometry(c->xdg_surface, &geo_box); | ||||
| 	if (mode == CurMove) { | ||||
| 		grab_x = cursor->x - view->x; | ||||
| 		grab_y = cursor->y - view->y; | ||||
| 		grab_x = cursor->x - c->x; | ||||
| 		grab_y = cursor->y - c->y; | ||||
| 	} else { | ||||
| 		grab_x = cursor->x + geo_box.x; | ||||
| 		grab_y = cursor->y + geo_box.y; | ||||
| @@ -637,7 +634,7 @@ render(struct wlr_surface *surface, int sx, int sy, void *data) | ||||
| { | ||||
| 	/* This function is called for every surface that needs to be rendered. */ | ||||
| 	struct render_data *rdata = data; | ||||
| 	struct dwl_view *view = rdata->view; | ||||
| 	Client *c = rdata->client; | ||||
| 	struct wlr_output *output = rdata->output; | ||||
|  | ||||
| 	/* We first obtain a wlr_texture, which is a GPU resource. wlroots | ||||
| @@ -650,14 +647,14 @@ render(struct wlr_surface *surface, int sx, int sy, void *data) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* The view has a position in layout coordinates. If you have two displays, | ||||
| 	 * one next to the other, both 1080p, a view on the rightmost display might | ||||
| 	/* The client has a position in layout coordinates. If you have two displays, | ||||
| 	 * one next to the other, both 1080p, a client on the rightmost display might | ||||
| 	 * have layout coordinates of 2000,100. We need to translate that to | ||||
| 	 * output-local coordinates, or (2000 - 1920). */ | ||||
| 	double ox = 0, oy = 0; | ||||
| 	wlr_output_layout_output_coords( | ||||
| 			output_layout, output, &ox, &oy); | ||||
| 	ox += view->x + sx, oy += view->y + sy; | ||||
| 	ox += c->x + sx, oy += c->y + sy; | ||||
|  | ||||
| 	/* We also have to apply the scale factor for HiDPI outputs. This is only | ||||
| 	 * part of the puzzle, dwl does not fully support HiDPI. */ | ||||
| @@ -670,10 +667,10 @@ render(struct wlr_surface *surface, int sx, int sy, void *data) | ||||
|  | ||||
| 	/* | ||||
| 	 * Those familiar with OpenGL are also familiar with the role of matricies | ||||
| 	 * in graphics programming. We need to prepare a matrix to render the view | ||||
| 	 * with. wlr_matrix_project_box is a helper which takes a box with a desired | ||||
| 	 * x, y coordinates, width and height, and an output geometry, then | ||||
| 	 * prepares an orthographic projection and multiplies the necessary | ||||
| 	 * in graphics programming. We need to prepare a matrix to render the | ||||
| 	 * client with. wlr_matrix_project_box is a helper which takes a box with | ||||
| 	 * a desired x, y coordinates, width and height, and an output geometry, | ||||
| 	 * then prepares an orthographic projection and multiplies the necessary | ||||
| 	 * transforms to produce a model-view-projection matrix. | ||||
| 	 * | ||||
| 	 * Naturally you can do this any way you like, for example to make a 3D | ||||
| @@ -695,23 +692,22 @@ render(struct wlr_surface *surface, int sx, int sy, void *data) | ||||
| } | ||||
|  | ||||
| void | ||||
| renderoutput(struct wl_listener *listener, void *data) | ||||
| rendermon(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	/* This function is called every time an output is ready to display a frame, | ||||
| 	 * generally at the output's refresh rate (e.g. 60Hz). */ | ||||
| 	struct dwl_output *output = | ||||
| 		wl_container_of(listener, output, frame); | ||||
| 	Monitor *m = wl_container_of(listener, m, frame); | ||||
|  | ||||
| 	struct timespec now; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &now); | ||||
|  | ||||
| 	/* wlr_output_attach_render makes the OpenGL context current. */ | ||||
| 	if (!wlr_output_attach_render(output->wlr_output, NULL)) { | ||||
| 	if (!wlr_output_attach_render(m->wlr_output, NULL)) { | ||||
| 		return; | ||||
| 	} | ||||
| 	/* The "effective" resolution can change if you rotate your outputs. */ | ||||
| 	int width, height; | ||||
| 	wlr_output_effective_resolution(output->wlr_output, &width, &height); | ||||
| 	wlr_output_effective_resolution(m->wlr_output, &width, &height); | ||||
| 	/* Begin the renderer (calls glViewport and some other GL sanity checks) */ | ||||
| 	wlr_renderer_begin(renderer, width, height); | ||||
|  | ||||
| @@ -719,21 +715,21 @@ renderoutput(struct wl_listener *listener, void *data) | ||||
| 	wlr_renderer_clear(renderer, color); | ||||
|  | ||||
| 	/* Each subsequent window we render is rendered on top of the last. Because | ||||
| 	 * our view list is ordered front-to-back, we iterate over it backwards. */ | ||||
| 	struct dwl_view *view; | ||||
| 	wl_list_for_each_reverse(view, &views, link) { | ||||
| 		if (!view->mapped) { | ||||
| 			/* An unmapped view should not be rendered. */ | ||||
| 	 * our client list is ordered front-to-back, we iterate over it backwards. */ | ||||
| 	Client *c; | ||||
| 	wl_list_for_each_reverse(c, &clients, link) { | ||||
| 		if (!c->mapped) { | ||||
| 			/* An unmapped client should not be rendered. */ | ||||
| 			continue; | ||||
| 		} | ||||
| 		struct render_data rdata = { | ||||
| 			.output = output->wlr_output, | ||||
| 			.view = view, | ||||
| 			.output = m->wlr_output, | ||||
| 			.client = c, | ||||
| 			.when = &now, | ||||
| 		}; | ||||
| 		/* This calls our render function for each surface among the | ||||
| 		 * xdg_surface's toplevel and popups. */ | ||||
| 		wlr_xdg_surface_for_each_surface(view->xdg_surface, | ||||
| 		wlr_xdg_surface_for_each_surface(c->xdg_surface, | ||||
| 				render, &rdata); | ||||
| 	} | ||||
|  | ||||
| @@ -743,12 +739,12 @@ renderoutput(struct wl_listener *listener, void *data) | ||||
| 	 * reason, wlroots provides a software fallback, which we ask it to render | ||||
| 	 * here. wlr_cursor handles configuring hardware vs software cursors for you, | ||||
| 	 * and this function is a no-op when hardware cursors are in use. */ | ||||
| 	wlr_output_render_software_cursors(output->wlr_output, NULL); | ||||
| 	wlr_output_render_software_cursors(m->wlr_output, NULL); | ||||
|  | ||||
| 	/* Conclude rendering and swap the buffers, showing the final frame | ||||
| 	 * on-screen. */ | ||||
| 	wlr_renderer_end(renderer); | ||||
| 	wlr_output_commit(output->wlr_output); | ||||
| 	wlr_output_commit(m->wlr_output); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -756,17 +752,17 @@ resizemouse(const Arg *arg) | ||||
| { | ||||
| 	double sx, sy; | ||||
| 	struct wlr_surface *surface; | ||||
| 	struct dwl_view *view = xytoview(cursor->x, cursor->y, | ||||
| 	Client *c = xytoclient(cursor->x, cursor->y, | ||||
| 			&surface, &sx, &sy); | ||||
| 	if (!view) { | ||||
| 	if (!c) { | ||||
| 		return; | ||||
| 	} | ||||
| 	struct wlr_box geo_box; | ||||
| 	wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box); | ||||
| 	wlr_xdg_surface_get_geometry(c->xdg_surface, &geo_box); | ||||
| 	wlr_cursor_warp_closest(cursor, NULL, | ||||
| 			view->x + geo_box.x + geo_box.width, | ||||
| 			view->y + geo_box.y + geo_box.height); | ||||
| 	moveresize(view, CurResize); | ||||
| 			c->x + geo_box.x + geo_box.width, | ||||
| 			c->y + geo_box.y + geo_box.height); | ||||
| 	moveresize(c, CurResize); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -804,12 +800,12 @@ void | ||||
| unmapnotify(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	/* Called when the surface is unmapped, and should no longer be shown. */ | ||||
| 	struct dwl_view *view = wl_container_of(listener, view, unmap); | ||||
| 	view->mapped = false; | ||||
| 	Client *c = wl_container_of(listener, c, unmap); | ||||
| 	c->mapped = false; | ||||
| } | ||||
|  | ||||
| bool | ||||
| xytosurface(struct dwl_view *view, double lx, double ly, | ||||
| xytosurface(Client *c, double lx, double ly, | ||||
| 		struct wlr_surface **surface, double *sx, double *sy) | ||||
| { | ||||
| 	/* | ||||
| @@ -819,15 +815,15 @@ xytosurface(struct dwl_view *view, double lx, double ly, | ||||
| 	 * surface pointer to that wlr_surface and the sx and sy coordinates to the | ||||
| 	 * coordinates relative to that surface's top-left corner. | ||||
| 	 */ | ||||
| 	double view_sx = lx - view->x; | ||||
| 	double view_sy = ly - view->y; | ||||
| 	double client_sx = lx - c->x; | ||||
| 	double client_sy = ly - c->y; | ||||
|  | ||||
| 	struct wlr_surface_state *state = &view->xdg_surface->surface->current; | ||||
| 	struct wlr_surface_state *state = &c->xdg_surface->surface->current; | ||||
|  | ||||
| 	double _sx, _sy; | ||||
| 	struct wlr_surface *_surface = NULL; | ||||
| 	_surface = wlr_xdg_surface_surface_at( | ||||
| 			view->xdg_surface, view_sx, view_sy, &_sx, &_sy); | ||||
| 			c->xdg_surface, client_sx, client_sy, &_sx, &_sy); | ||||
|  | ||||
| 	if (_surface != NULL) { | ||||
| 		*sx = _sx; | ||||
| @@ -839,16 +835,16 @@ xytosurface(struct dwl_view *view, double lx, double ly, | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| struct dwl_view * | ||||
| xytoview(double lx, double ly, | ||||
| Client * | ||||
| xytoclient(double lx, double ly, | ||||
| 		struct wlr_surface **surface, double *sx, double *sy) | ||||
| { | ||||
| 	/* This iterates over all of our surfaces and attempts to find one under the | ||||
| 	 * cursor. This relies on views being ordered from top-to-bottom. */ | ||||
| 	struct dwl_view *view; | ||||
| 	wl_list_for_each(view, &views, link) { | ||||
| 		if (xytosurface(view, lx, ly, surface, sx, sy)) { | ||||
| 			return view; | ||||
| 	 * cursor. This relies on clients being ordered from top-to-bottom. */ | ||||
| 	Client *c; | ||||
| 	wl_list_for_each(c, &clients, link) { | ||||
| 		if (xytosurface(c, lx, ly, surface, sx, sy)) { | ||||
| 			return c; | ||||
| 		} | ||||
| 	} | ||||
| 	return NULL; | ||||
| @@ -909,17 +905,17 @@ main(int argc, char *argv[]) | ||||
|  | ||||
| 	/* Configure a listener to be notified when new outputs are available on the | ||||
| 	 * backend. */ | ||||
| 	wl_list_init(&outputs); | ||||
| 	new_output.notify = createoutput; | ||||
| 	wl_list_init(&mons); | ||||
| 	new_output.notify = createmon; | ||||
| 	wl_signal_add(&backend->events.new_output, &new_output); | ||||
|  | ||||
| 	/* Set up our list of views and the xdg-shell. The xdg-shell is a Wayland | ||||
| 	/* Set up our list of clients and the xdg-shell. The xdg-shell is a Wayland | ||||
| 	 * protocol which is used for application windows. For more detail on | ||||
| 	 * shells, refer to my article: | ||||
| 	 * | ||||
| 	 * https://drewdevault.com/2018/07/29/Wayland-shells.html | ||||
| 	 */ | ||||
| 	wl_list_init(&views); | ||||
| 	wl_list_init(&clients); | ||||
| 	xdg_shell = wlr_xdg_shell_create(wl_display); | ||||
| 	new_xdg_surface.notify = createnotify; | ||||
| 	wl_signal_add(&xdg_shell->events.new_surface, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user