21#include "ctwm_atoms.h"
55static XrmOptionDescRec
table [] = {
56 {
"-xrm", NULL, XrmoptionResArg, (XPointer) NULL},
82 char **cliargv = NULL;
87 if(!
Scr->workSpaceManagerActive) {
103 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
115 if(XGetCommand(
dpy, twm_win->
w, &cliargv, &cliargc)) {
119 XrmDatabase db = NULL;
121 XrmParseCommand(&db,
table, 1,
"ctwm", &cliargc, cliargv);
122 XFreeStringList(cliargv);
123 status = XrmGetResource(db,
"ctwm.workspace",
"Ctwm.Workspace",
125 if((status == True) && (value.size != 0)) {
127 char wrkSpcList[512];
132 XrmDestroyDatabase(db);
139 unsigned long nitems, bytesafter;
142 if(XGetWindowProperty(
dpy, twm_win->
w, XA_WM_OCCUPATION, 0L, 2500, False,
143 XA_STRING, &actual_type, &actual_format, &nitems,
144 &bytesafter, &prop) == Success) {
170 if(!
Scr->TransientHasOccupation) {
179 else if(twm_win->
group != 0) {
189 if(occupation_hint != 0) {
209 if(
Scr->numVscreens > 1) {
211 for(vs =
Scr->vScreenList; vs != NULL; vs = vs->
next) {
237 XChangeProperty(
dpy, twm_win->
w, XA_WM_OCCUPATION, XA_STRING, 8,
238 PropModeReplace, (
unsigned char *) wsstr,
len);
251 int state = NormalState;
256 && (state == NormalState || state == IconicState
257 || state == InactiveState))) {
258 if(twm_win->
wmhints->flags & StateHint) {
259 state = twm_win->
wmhints->initial_state;
263 if(state == InactiveState) {
268 if(state == NormalState) {
366 wlist2 = wlist1->
next;
367 wlist2 = wlist2 ? wlist2 :
Scr->workSpaceMgr.workSpaceList;
403 wlist1 =
Scr->workSpaceMgr.workSpaceList;
409 while(wlist1->
next != wlist2 && wlist1->
next != NULL) {
410 wlist1 = wlist1->
next;
452 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
454 newoccupation |= 1 << ws->
number;
458 if(newoccupation != 0) {
481 if(newoccupation == 0) {
497 for(tw =
Scr->FirstWindow; tw != NULL; tw = tw->
next) {
505 for(tw =
Scr->FirstWindow; tw != NULL; tw = tw->
next) {
512 for(tw =
Scr->FirstWindow; tw != NULL; tw = tw->
next) {
526 if((!
Scr->WarpUnmapped) && (! tw->
mapped)) {
563 Scr->iconmgr =
Scr->workSpaceMgr.workSpaceList->iconmgr;
603 const int lines =
Scr->workSpaceMgr.lines;
604 const int columns =
Scr->workSpaceMgr.columns;
605 const int bwidth =
Scr->vScreenList->wsw->bwidth;
606 const int bheight =
Scr->vScreenList->wsw->bheight;
607 const int vspace = occwin->
vspace;
608 const int hspace = occwin->
hspace;
609 const int height = ((bheight + vspace) * lines) + bheight + (2 * vspace);
614 if(!
Scr->workSpaceManagerActive) {
619 occwin->
font =
Scr->IconManagerFont;
620 occwin->
cp =
Scr->IconManagerC;
621#ifdef COLOR_BLIND_USER
625 if(!
Scr->BeNiceToColormap) {
631 occwin->
lines = lines;
641 XRectangle logical_rect;
645 int bb_width, ws_width;
649 &inc_rect, &logical_rect);
650 bbwidth = logical_rect.width;
653 &inc_rect, &logical_rect);
654 bbwidth =
MAX(bbwidth, logical_rect.width);
658 &inc_rect, &logical_rect);
659 bbwidth =
MAX(bbwidth, logical_rect.width);
672 occwin->
owidth = bbwidth + 2 *
Scr->WMgrButtonShadowDepth + 2;
680 bb_width = 3 * (bbwidth + hspace) + hspace;
687 ws_width = columns * (bwidth + hspace) + hspace;
690 width =
MAX(bb_width, ws_width);
695 w = occwin->
w = XCreateSimpleWindow(
dpy,
Scr->Root, 0, 0, width, height,
711 occwin->
obuttonw = calloc(
Scr->workSpaceMgr.count,
sizeof(Window));
713 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
714 int idx = (j * columns) + i;
721 occwin->
obuttonw[idx] = XCreateSimpleWindow(
dpy, w,
750 if(!
Scr->BeNiceToColormap) {
758 tw = XCreateSimpleWindow(
dpy, w, Dummy, Dummy, Dummy, Dummy, 0,
763 tw = XCreateSimpleWindow(
dpy, w, Dummy, Dummy, Dummy, Dummy, 0,
768 tw = XCreateSimpleWindow(
dpy, w, Dummy, Dummy, Dummy, Dummy, 0,
777 XSizeHints sizehints;
780 sizehints.flags = PBaseSize | PMinSize | PMaxSize;
781 sizehints.min_width = width;
782 sizehints.min_height = height;
783 sizehints.base_width = width;
784 sizehints.base_height = height;
785 sizehints.max_width = width;
786 sizehints.max_height = height;
788 wmhints.flags = InputHint | StateHint;
789 wmhints.input = True;
790 wmhints.initial_state = NormalState;
793 NULL, 0, &sizehints, &wmhints, NULL);
804 fprintf(stderr,
"cannot create occupy window, exiting...\n");
819 unsigned long attrmask;
820 XSetWindowAttributes attr;
821 XWindowAttributes wattr;
823 attr.cursor =
Scr->ButtonCursor;
825 XChangeWindowAttributes(
dpy, w, attrmask, &attr);
827 XGetWindowAttributes(
dpy, w, &wattr);
828 attrmask = wattr.your_event_mask | KeyPressMask | KeyReleaseMask
830 XSelectInput(
dpy, w, attrmask);
840#define EVT (ButtonPressMask | ButtonReleaseMask | ExposureMask)
841#define BTN_IPT_CTX(win) \
842 XSelectInput(dpy, (win), EVT); \
843 XSaveContext(dpy, (win), TwmContext, (XPointer) tmp_win); \
844 XSaveContext(dpy, (win), ScreenContext, (XPointer) Scr);
847 ; ws != NULL ; ws = ws->next) {
876 int bwidth, bheight, owidth, oheight;
887 if(occwin->
width == neww && occwin->
height == newh) {
896 lines =
Scr->workSpaceMgr.lines;
897 columns =
Scr->workSpaceMgr.columns;
900 bwidth = (neww - columns * hspace) / columns;
901 bheight = (newh - (lines + 2) * vspace) / (lines + 1);
913 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
914 XMoveResizeWindow(
dpy, occwin->
obuttonw [j * columns + i],
915 i * (bwidth + hspace) + (hspace / 2),
916 j * (bheight + vspace) + (vspace / 2),
929 hspace = (neww - 3 * owidth) / 4;
931 y = ((bheight + vspace) * lines) + ((3 * vspace) / 2);
932 XMoveResizeWindow(
dpy, occwin->
OK,
x,
y, owidth, oheight);
933 x += owidth + hspace;
934 XMoveResizeWindow(
dpy, occwin->
cancel,
x,
y, owidth, oheight);
935 x += owidth + hspace;
940 occwin->
width = neww;
960 occwin =
Scr->workSpaceMgr.occupyWindow;
961 width = occwin->
width;
966 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
995 if(!
Scr->workSpaceManagerActive) {
1005 buttonW =
event->xbutton.window;
1011 XGrabPointer(
dpy,
Scr->Root, True,
1012 ButtonPressMask | ButtonReleaseMask,
1013 GrabModeAsync, GrabModeAsync,
1014 Scr->Root, None, CurrentTime);
1017 occupyW =
Scr->workSpaceMgr.occupyWindow;
1018 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
1026 int mask = 1 << ws->
number;
1033 else if(buttonW == occupyW->
OK) {
1045 else if(buttonW == occupyW->
cancel) {
1055 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
1064 XUngrabPointer(
dpy, CurrentTime);
1076 unsigned int width, height;
1087 occupyWindow =
Scr->workSpaceMgr.occupyWindow;
1089 w = occupyWindow->
w;
1097 occupy_twm = occupyWindow->
twm_win;
1125 XMapWindow(
dpy, occupyWindow->
w);
1126 XMapWindow(
dpy, occupy_twm->
frame);
1160 int changedoccupation;
1162 if((newoccupation == 0)
1177 XChangeProperty(
dpy, tmp_win->
w, XA_WM_OCCUPATION, XA_STRING, 8,
1178 PropModeReplace, (
unsigned char *) namelist,
len);
1203 tmp_win->
occupation = newoccupation & ~oldoccupation;
1220 for(vs =
Scr->vScreenList; vs != NULL; vs = vs->
next) {
1237 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
1238 int mask = 1 << ws->
number;
1239 if(oldoccupation & mask) {
1240 if(!(newoccupation & mask)) {
1241 int final_x, final_y;
1244 XMoveWindow(
dpy, tmp_win->
frame, final_x, final_y);
1260 XChangeProperty(
dpy, tmp_win->
w, XA_WM_OCCUPATION, XA_STRING, 8,
1261 PropModeReplace, (
unsigned char *) namelist,
len);
1285 if(
Scr->workSpaceMgr.noshowoccupyall) {
1298 changedoccupation = oldoccupation ^ newoccupation;
1299 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
1300 int mask = 1 << ws->
number;
1301 if(changedoccupation & mask) {
1302 if(newoccupation & mask) {
1325 if(!
Scr->TransientHasOccupation) {
1326 for(t =
Scr->FirstWindow; t != NULL; t = t->
next) {
1329 t->
group == tmp_win->
w)) {
1356 if(!
Scr->workSpaceManagerActive) {
1365 if(
occupyWin != NULL &&
Scr->workSpaceMgr.occupyWindow->twm_win->mapped) {
1383 if(!
Scr->TransientHasOccupation) {
1417 if(strcmp(workspace,
"all") == 0) {
1418 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
1425 if(strncmp(workspace,
"ws:", 3) == 0) {
1452 enum { O_SET, O_ADD, O_REM } mode;
1453 char *wrkSpcName, *tokst;
1467 else if(*res ==
'-') {
1477 for(wrkSpcName = strtok_r(res,
" ", &tokst) ; wrkSpcName
1478 ; wrkSpcName = strtok_r(NULL,
" ", &tokst)) {
1479 if(strcmp(wrkSpcName,
"all") == 0) {
1483 if(strcmp(wrkSpcName,
"current") == 0) {
1493 mask |= (1 << ws->
number);
1496 fprintf(stderr,
"unknown workspace : %s\n", wrkSpcName);
1514 fprintf(stderr,
"%s(): Unreachable.\n", __func__);
1526 char wrkSpcName[256];
1534 prop = (
char *) _prop;
1538 l += strlen(prop) + 1;
1539 prop += strlen(prop) + 1;
1540 if(strcmp(wrkSpcName,
"all") == 0) {
1547 mask |= (1 << ws->
number);
1550 fprintf(stderr,
"unknown workspace : %s\n", wrkSpcName);
1557 fprintf(stderr,
"%s('%s') -> 0x%x\n", __func__, dbs, mask);
1580 *prop = strdup(
"all");
1585 memset(wss, 0,
sizeof(wss));
1588 for(ws =
Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->
next) {
1589 if(mask & (1 << ws->
number)) {
1590 wss[i++] = ws->
label;
1596 *prop = malloc(
len);
1598 for(i = 0 ; wss[i] != NULL ; i++) {
1599 strcpy((*prop +
len), wss[i]);
1600 len += strlen(wss[i]) + 1;
1606 fprintf(stderr,
"%s(0x%x) -> %d:'%s'\n", __func__, mask,
len, dbs);
1621# pragma GCC diagnostic push
1622# pragma GCC diagnostic ignored "-Wunused-function"
1634 dbs = malloc(
len * 2);
1637 size_t slen = strlen(prop + i);
1639 strcpy(dbs + j, (prop + i));
1641 strcpy(dbs + j + slen,
"\\0");
1648# pragma GCC diagnostic pop
TwmWindow * AddWindow(Window w, AWType wtype, IconMgr *iconp, VirtualScreen *vs)
static XrmOptionDescRec table[]
bool RestartPreviousState
void Draw3DBorder(Window w, int x, int y, int width, int height, int bw, ColorPair cp, ButtonState state, bool fill, bool forcebw)
void PaintWsButton(PWBType which, VirtualScreen *vs, Window w, char *label, ColorPair cp, ButtonState state)
void EwmhSet_NET_WM_DESKTOP(TwmWindow *twm_win)
int EwmhGetOccupation(TwmWindow *twm_win)
int frame_x
X position on screen of frame.
int frame_y
Y position on screen of frame.
Window frame
The X window for the overall frame.
int frame_bw
2d border width.
int frame_bw3D
3d border width.
void RemoveIconManager(TwmWindow *tmp_win)
WList * AddIconManager(TwmWindow *tmp_win)
int match(const char *p, const char *t)
void AddToList(name_list **list_head, const char *name, void *ptr)
void * LookInList(name_list *list_head, const char *name, XClassHint *class)
void Occupy(TwmWindow *twm_win)
void OccupyHandleButtonEvent(XEvent *event)
static ColorPair occupyButtoncp
void RemoveFromWorkSpace(char *wname, TwmWindow *twm_win)
unsigned int GetMaskFromProperty(unsigned char *_prop, unsigned long len)
static int GetMaskFromResource(TwmWindow *win, char *res)
static char * mk_nullsep_string(const char *prop, int len)
void PaintOccupyWindow(void)
static char * everywhere_string
void OccupyAll(TwmWindow *twm_win)
void AddToWorkSpace(char *wname, TwmWindow *twm_win)
static bool CanChangeOccupation(TwmWindow **twm_winp)
void MoveToPrevWorkSpace(VirtualScreen *vs, TwmWindow *twm_win)
void CreateOccupyWindow(void)
static char * cancel_string
void ChangeOccupation(TwmWindow *tmp_win, int newoccupation)
int GetPropertyFromMask(unsigned int mask, char **prop)
void MoveToNextWorkSpace(VirtualScreen *vs, TwmWindow *twm_win)
void WmgrRedoOccupation(TwmWindow *win)
bool AddToClientsList(char *workspace, char *client)
void WMgrRemoveFromCurrentWorkSpace(VirtualScreen *vs, TwmWindow *win)
void ResizeOccupyWindow(TwmWindow *win)
void MoveToNextWorkSpaceAndFollow(VirtualScreen *vs, TwmWindow *twm_win)
void MoveToPrevWorkSpaceAndFollow(VirtualScreen *vs, TwmWindow *twm_win)
void ToggleOccupation(char *wname, TwmWindow *twm_win)
void SetupOccupation(TwmWindow *twm_win, int occupation_hint)
void WMgrAddToCurrentWorkSpaceAndWarp(VirtualScreen *vs, char *winname)
void OtpSetPriority(TwmWindow *twm_win, WinType wintype, int new_pri, int where)
void OtpRaise(TwmWindow *twm_win, WinType wintype)
Info and control for every X Window we take over.
struct TwmWindow * next
Next TwmWindow on the Screen.
bool iswspmgr
This is a workspace manager window.
bool isiconmgr
This is an icon manager window.
XWMHints * wmhints
Window manager hints.
Window w
The actual X Window handle.
bool istransient
This is a transient window.
char * name
Current window name. Points into TwmWindow::names.
int occupation
Workspaces the window is in (bitmap).
struct VirtualScreen * vs
Where the window is currently mapped (may be NULL).
bool mapped
Is the window mapped ?
XClassHint class
Window class info. From XGetClassHint().
struct VirtualScreen * parent_vs
Where the window is parented. Always set.
XWindowAttributes attr
Window attributes from XGetWindowAttributes().
Window transientfor
What window it's transient for.
Window group
Window group, from WM hints.
struct VirtualScreen * next
struct WorkSpaceWindow * wsw
void safe_strncpy(char *dest, const char *src, size_t size)
void GetColor(int kind, Pixel *what, const char *name)
Get info from the server about a given color.
void GetShadeColors(ColorPair *cp)
Try and create a 'shaded' version of a color for prettier UI.
void ReparentFrameAndIcon(TwmWindow *tmp_win)
void Vanish(VirtualScreen *vs, TwmWindow *tmp_win)
void DisplayWin(VirtualScreen *vs, TwmWindow *tmp_win)
void DeIconify(TwmWindow *tmp_win)
void RemoveWindowFromRegion(TwmWindow *tmp_win)
bool PlaceWindowInRegion(TwmWindow *tmp_win, int *final_x, int *final_y)
bool visible(const TwmWindow *tmp_win)
bool GetWMState(Window w, int *statep, Window *iwp)
TwmWindow * GetTwmWindow(Window w)
int restore_mask(Window w, long restore)
bool ConstrainByLayout(RLayout *layout, int move_off_res, int *left, int width, int *top, int height)
long mask_out_event(Window w, long ignore_event)
void SetMapStateProp(TwmWindow *tmp_win, int state)
void WarpToWindow(TwmWindow *t, bool must_raise)
void WMapAddWindowToWorkspace(TwmWindow *win, WorkSpace *ws)
bool WMapWindowMayBeAdded(TwmWindow *win)
void WMapRemoveWindowFromWorkspace(TwmWindow *win, WorkSpace *ws)
void GotoPrevWorkSpace(VirtualScreen *vs)
WorkSpace * GetWorkspace(const char *wname)
void GotoNextWorkSpace(VirtualScreen *vs)