From 22983c562c3622a3428750dba298de4a74d4829a Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Wed, 19 May 2021 09:06:14 +0900 Subject: [PATCH] client: Implement resizing and changing the visibility of clients This commit implements functions to resize clients, and change their visibility by moving them out of the root screen. --- client.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- client.h | 30 +++++++- 2 files changed, 243 insertions(+), 3 deletions(-) diff --git a/client.c b/client.c index 0ac205b..7d3049f 100644 --- a/client.c +++ b/client.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,14 +6,21 @@ #include "common.h" #include "client.h" #include "workspace.h" +#include "mwm.h" +#include "monitor.h" struct client { - struct geom geom; Window window; + struct geom geom; + int needs_redraw; + + int border_width; client_flags_t flags; struct workspace *workspace; }; +extern struct mwm *__mwm; + int client_new(Window window, XWindowAttributes *attrs, struct client **client) { struct client *cl; @@ -75,3 +83,209 @@ int client_get_geometry(struct client *client, struct geom *geom) memcpy(geom, &client->geom, sizeof(*geom)); return(0); } + +Window client_get_window(struct client *client) +{ + return(client->window); +} + +int client_configure(struct client *client) +{ + XConfigureEvent configure_event; + Display *display; + Window window; + + display = mwm_get_display(__mwm); + window = client->window; + + configure_event.type = ConfigureNotify; + configure_event.display = display; + configure_event.event = window; + configure_event.window = window; + configure_event.x = client->geom.x; + configure_event.y = client->geom.y; + configure_event.width = client->geom.w; + configure_event.height = client->geom.h; + configure_event.border_width = client->border_width; + configure_event.above = None; + configure_event.override_redirect = False; + + if(!XSendEvent(display, window, False, StructureNotifyMask, + (XEvent*)&configure_event)) { + return(-EIO); + } + + return(0); +} + +int client_redraw(struct client *client) +{ + if(!client) { + return(-EINVAL); + } + + if(client_is_visible(client)) { + XMapRaised(mwm_get_display(__mwm), client->window); + XMoveWindow(mwm_get_display(__mwm), client->window, + client->geom.x, client->geom.y); + } else { + XMoveWindow(mwm_get_display(__mwm), client->window, + client->geom.w * -2, client->geom.y); + } + + client->needs_redraw = 0; + + return(0); +} + +int client_get_border(struct client *client) +{ + return(client->border_width); +} + +void client_set_border(struct client *client, int border) +{ + client->border_width = border; + return; +} + +struct monitor* client_get_viewer(struct client *client) +{ + if(client->workspace) { + return(workspace_get_viewer(client->workspace)); + } + + return(NULL); +} + +int client_is_floating(struct client *client) +{ + struct monitor *viewer; + + if(!client) { + return(FALSE); + } + + if(client->flags & CLIENT_FLOATING) { + return(TRUE); + } + + viewer = client_get_viewer(client); + + return(viewer ? monitor_is_floating(viewer) : FALSE); +} + +int client_set_workspace(struct client *client, struct workspace *workspace) +{ + if(!client || !workspace) { + return(-EINVAL); + } + + client->workspace = workspace; + return(0); +} + +struct workspace* client_get_workspace(struct client *client) +{ + return(client->workspace); +} + +int client_is_visible(struct client *client) +{ + struct workspace *workspace; + + workspace = client_get_workspace(client); + + if(!workspace) { + return(FALSE); + } + + return(workspace_get_viewer(workspace) != NULL); +} + +int client_is_tiled(struct client *client) +{ + if(!client) { + return(FALSE); + } + + if(client->flags & (CLIENT_FLOATING | + CLIENT_FULLSCREEN | + CLIENT_FIXED)) { + return(FALSE); + } + + return(TRUE); +} + +int client_change_geometry(struct client *client, struct geom *geom) +{ + if(!client || !geom) { + return(-EINVAL); + } + + /* If the client is floating, we'll allow it */ + if(client_is_floating(client)) { + client_set_geometry(client, geom); + } + + return(0); +} + +int client_show(struct client *client) +{ +#if MWM_DEBUG + printf("XMoveResizeWindow(%p, %ld, %d, %d, %d, %d)\n", + (void*)client, client->window, + client->geom.x, client->geom.y, + client->geom.w, client->geom.h); +#endif /* MWM_DEBUG */ + + XMoveResizeWindow(mwm_get_display(__mwm), client->window, + client->geom.x, client->geom.y, + client->geom.w, client->geom.h); + XMapRaised(mwm_get_display(__mwm), client->window); + + return(0); +} + +int client_needs_redraw(struct client *client) +{ + if(!client) { + return(-EINVAL); + } + + client->needs_redraw = 1; + workspace_needs_redraw(client->workspace); + + return(0); +} + +int client_focus(struct client *client) +{ + if(!client) { + return(-EINVAL); + } + + XSetInputFocus(mwm_get_display(__mwm), client->window, RevertToPointerRoot, CurrentTime); + + return(0); +} + +int client_set_state(struct client *client, const long state) +{ + long wm_state; + long data[2]; + + data[0] = state; + data[1] = None; + + if(mwm_get_atom(__mwm, "WM_STATE", &wm_state) < 0) { + return(-EIO); + } + + XChangeProperty(mwm_get_display(__mwm), client->window, + wm_state, wm_state, 32, + PropModeReplace, (unsigned char*)data, 2); + return(0); +} diff --git a/client.h b/client.h index f1a338b..ad123ff 100644 --- a/client.h +++ b/client.h @@ -12,8 +12,34 @@ typedef enum { } client_flags_t; struct client; +struct workspace; +struct geom; -int client_new(Window window, XWindowAttributes *attrs, struct client**); -int client_free(struct client**); +int client_new(Window window, XWindowAttributes *attrs, struct client **client); +int client_free(struct client **client); + +int client_get_border(struct client *client); +void client_set_border(struct client *client, int border); + +Window client_get_window(struct client *client); +int client_owns_window(struct client *client, Window *window); +int client_configure(struct client *client); +int client_redraw(struct client *client); +int client_is_floating(struct client *client); +int client_is_visible(struct client *client); +int client_is_tiled(struct client *client); +int client_get_geometry(struct client *client, struct geom *geom); +int client_set_geometry(struct client *client, struct geom *geom); +int client_change_geometry(struct client *client, struct geom *geom); + +int client_set_workspace(struct client *client, struct workspace *workspace); +struct workspace* client_get_workspace(struct client *client); +struct monitor* client_get_viewer(struct client *client); +int client_show(struct client *client); + +int client_needs_redraw(struct client *client); +int client_focus(struct client *client); + +int client_set_state(struct client *client, long state); #endif /* MWM_CLIENT_H */ -- 2.47.3