diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-04-15 16:46:09 +0200 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-04-15 16:46:09 +0200 |
| commit | b94d7cea0d3a05b3e05664fe697431b618a43328 (patch) | |
| tree | f3f80fc2ea83a1a3f576505c1d43e88ab4abb5ef | |
| parent | 07b63258b0acc1f715111642d1e95d34d811e6f9 (diff) | |
| download | glitch-b94d7cea0d3a05b3e05664fe697431b618a43328.tar.gz | |
Add save and restore position and sizes of windows for floating/tiled
| -rw-r--r-- | glitch.h | 3 | ||||
| -rw-r--r-- | manager.c | 64 |
2 files changed, 65 insertions, 2 deletions
| @@ -50,6 +50,9 @@ typedef struct Client { | |||
| 50 | Window window; | 50 | Window window; |
| 51 | struct Client *next; | 51 | struct Client *next; |
| 52 | struct Client *prev; | 52 | struct Client *prev; |
| 53 | int saved_x, saved_y; | ||
| 54 | unsigned int saved_w, saved_h; | ||
| 55 | int has_saved_state; | ||
| 53 | } Client; | 56 | } Client; |
| 54 | 57 | ||
| 55 | typedef struct { | 58 | typedef struct { |
| @@ -130,6 +130,11 @@ static void add_client(Window w) { | |||
| 130 | new_c->window = w; | 130 | new_c->window = w; |
| 131 | new_c->next = wm.clients; | 131 | new_c->next = wm.clients; |
| 132 | new_c->prev = NULL; | 132 | new_c->prev = NULL; |
| 133 | new_c->saved_x = 0; | ||
| 134 | new_c->saved_y = 0; | ||
| 135 | new_c->saved_w = 0; | ||
| 136 | new_c->saved_h = 0; | ||
| 137 | new_c->has_saved_state = 0; | ||
| 133 | 138 | ||
| 134 | if (wm.clients) { | 139 | if (wm.clients) { |
| 135 | wm.clients->prev = new_c; | 140 | wm.clients->prev = new_c; |
| @@ -1678,9 +1683,64 @@ void apply_tiling_layout(void) { | |||
| 1678 | 1683 | ||
| 1679 | void toggle_layout(const Arg *arg) { | 1684 | void toggle_layout(const Arg *arg) { |
| 1680 | (void)arg; | 1685 | (void)arg; |
| 1681 | wm.layout_modes[wm.current_desktop] = (wm.layout_modes[wm.current_desktop] == LAYOUT_TILING) ? LAYOUT_FLOATING : LAYOUT_TILING; | 1686 | LayoutMode current_mode = wm.layout_modes[wm.current_desktop]; |
| 1682 | if (wm.layout_modes[wm.current_desktop] == LAYOUT_TILING) { | 1687 | |
| 1688 | if (current_mode == LAYOUT_FLOATING) { | ||
| 1689 | // Moving to TILING, save floating positions | ||
| 1690 | for (Client *c = wm.clients; c; c = c->next) { | ||
| 1691 | if (!window_exists(c->window)) continue; | ||
| 1692 | |||
| 1693 | unsigned long desktop; | ||
| 1694 | Atom actual_type; | ||
| 1695 | int actual_format; | ||
| 1696 | unsigned long nitems, bytes_after; | ||
| 1697 | unsigned char *prop = NULL; | ||
| 1698 | |||
| 1699 | int status = XGetWindowProperty(wm.dpy, c->window, _NET_WM_DESKTOP, 0, 1, False, XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after, &prop); | ||
| 1700 | if (status == Success && prop && nitems > 0) { | ||
| 1701 | desktop = *(unsigned long *)prop; | ||
| 1702 | XFree(prop); | ||
| 1703 | if (desktop == wm.current_desktop && !is_sticky(c->window) && !is_always_on_top(c->window) && !has_wm_state(c->window, _NET_WM_STATE_FULLSCREEN)) { | ||
| 1704 | XWindowAttributes attr; | ||
| 1705 | if (XGetWindowAttributes(wm.dpy, c->window, &attr)) { | ||
| 1706 | c->saved_x = attr.x; | ||
| 1707 | c->saved_y = attr.y; | ||
| 1708 | c->saved_w = attr.width; | ||
| 1709 | c->saved_h = attr.height; | ||
| 1710 | c->has_saved_state = 1; | ||
| 1711 | } | ||
| 1712 | } | ||
| 1713 | } else if (prop) { | ||
| 1714 | XFree(prop); | ||
| 1715 | } | ||
| 1716 | } | ||
| 1717 | wm.layout_modes[wm.current_desktop] = LAYOUT_TILING; | ||
| 1683 | apply_tiling_layout(); | 1718 | apply_tiling_layout(); |
| 1719 | } else { | ||
| 1720 | // Moving to FLOATING, restore positions | ||
| 1721 | wm.layout_modes[wm.current_desktop] = LAYOUT_FLOATING; | ||
| 1722 | for (Client *c = wm.clients; c; c = c->next) { | ||
| 1723 | if (!window_exists(c->window)) continue; | ||
| 1724 | if (c->has_saved_state) { | ||
| 1725 | unsigned long desktop; | ||
| 1726 | Atom actual_type; | ||
| 1727 | int actual_format; | ||
| 1728 | unsigned long nitems, bytes_after; | ||
| 1729 | unsigned char *prop = NULL; | ||
| 1730 | |||
| 1731 | int status = XGetWindowProperty(wm.dpy, c->window, _NET_WM_DESKTOP, 0, 1, False, XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after, &prop); | ||
| 1732 | if (status == Success && prop && nitems > 0) { | ||
| 1733 | desktop = *(unsigned long *)prop; | ||
| 1734 | XFree(prop); | ||
| 1735 | if (desktop == wm.current_desktop) { | ||
| 1736 | XMoveResizeWindow(wm.dpy, c->window, c->saved_x, c->saved_y, c->saved_w, c->saved_h); | ||
| 1737 | c->has_saved_state = 0; | ||
| 1738 | } | ||
| 1739 | } else if (prop) { | ||
| 1740 | XFree(prop); | ||
| 1741 | } | ||
| 1742 | } | ||
| 1743 | } | ||
| 1684 | } | 1744 | } |
| 1685 | redraw_widgets(); | 1745 | redraw_widgets(); |
| 1686 | log_message(stdout, LOG_DEBUG, "Toggled layout for desktop %d to %s", wm.current_desktop, wm.layout_modes[wm.current_desktop] == LAYOUT_TILING ? "TILING" : "FLOATING"); | 1746 | log_message(stdout, LOG_DEBUG, "Toggled layout for desktop %d to %s", wm.current_desktop, wm.layout_modes[wm.current_desktop] == LAYOUT_TILING ? "TILING" : "FLOATING"); |
