Newer
Older
Olivier Fourdan
committed
clientGetNetStruts (Client * c)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
unsigned long old_flags, new_flags;
int old_struts[STRUTS_SIZE];
Olivier Fourdan
committed
int nitems;
int i;
g_return_val_if_fail (c != NULL, FALSE);
TRACE ("entering clientGetNetStruts for \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
Olivier Fourdan
committed
/* Save old values */
old_flags = c->flags & (CLIENT_FLAG_HAS_STRUT | CLIENT_FLAG_HAS_STRUT_PARTIAL);
for (i = 0; i < STRUTS_SIZE; i++)
Olivier Fourdan
committed
{
old_struts[i] = c->struts[i];
Olivier Fourdan
committed
c->struts[i] = 0;
}
FLAG_UNSET (c->flags, CLIENT_FLAG_HAS_STRUT);
FLAG_UNSET (c->flags, CLIENT_FLAG_HAS_STRUT_PARTIAL);
if (getCardinalList (display_info, c->window, NET_WM_STRUT_PARTIAL, &struts, &nitems))
Olivier Fourdan
committed
{
if (nitems != STRUTS_SIZE)
Olivier Fourdan
committed
{
if (struts)
{
XFree (struts);
}
/* Restore old values */
if (old_flags)
{
FLAG_SET (c->flags, old_flags);
for (i = 0; i < STRUTS_SIZE; i++)
{
c->struts[i] = old_struts[i];
}
}
return FALSE;
Olivier Fourdan
committed
}
FLAG_SET (c->flags, CLIENT_FLAG_HAS_STRUT);
FLAG_SET (c->flags, CLIENT_FLAG_HAS_STRUT_PARTIAL);
for (i = 0; i < STRUTS_SIZE; i++)
Olivier Fourdan
committed
{
c->struts[i] = (int) struts[i];
}
XFree (struts);
}
else if (getCardinalList (display_info, c->window, NET_WM_STRUT, &struts, &nitems))
Olivier Fourdan
committed
{
if (nitems != 4)
{
if (struts)
{
XFree (struts);
}
/* Restore old values */
if (old_flags)
{
FLAG_SET (c->flags, old_flags);
for (i = 0; i < STRUTS_SIZE; i++)
{
c->struts[i] = old_struts[i];
}
}
return FALSE;
Olivier Fourdan
committed
}
FLAG_SET (c->flags, CLIENT_FLAG_HAS_STRUT);
for (i = 0; i < 4; i++)
{
c->struts[i] = (int) struts[i];
}
for (i = 4; i < STRUTS_SIZE; i++)
Olivier Fourdan
committed
{
Olivier Fourdan
committed
c->struts[i] = 0;
Olivier Fourdan
committed
}
/* Fill(in values as for partial struts */
Olivier Fourdan
committed
c->struts[STRUTS_TOP_START_X] = c->struts[STRUTS_BOTTOM_START_X] = 0;
c->struts[STRUTS_TOP_END_X] = c->struts[STRUTS_BOTTOM_END_X] =
c->screen_info->width;
Olivier Fourdan
committed
c->struts[STRUTS_LEFT_START_Y] = c->struts[STRUTS_RIGHT_START_Y] = 0;
c->struts[STRUTS_LEFT_END_Y] = c->struts[STRUTS_RIGHT_END_Y] =
c->screen_info->height;
Olivier Fourdan
committed
XFree (struts);
}
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT))
{
clientValidateNetStrut (c);
}
/* check for a change in struts flags */
new_flags = c->flags & (CLIENT_FLAG_HAS_STRUT | CLIENT_FLAG_HAS_STRUT_PARTIAL);
if (old_flags != new_flags)
{
return TRUE;
}
/* Flags haven't changed, check values */
if (new_flags)
{
for (i = 0; i < STRUTS_SIZE; i++)
{
if (old_struts[i] != c->struts[i])
{
return TRUE;
}
}
}
return FALSE;
Olivier Fourdan
committed
}
void
clientSetNetActions (Client * c)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
Olivier Fourdan
committed
Atom atoms[16];
Olivier Fourdan
committed
g_return_if_fail (c != NULL);
TRACE ("entering clientSetNetActions");
screen_info = c->screen_info;
display_info = screen_info->display_info;
atoms[i++] = display_info->atoms[NET_WM_ACTION_CLOSE];
Olivier Fourdan
committed
atoms[i++] = display_info->atoms[NET_WM_ACTION_ABOVE];
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
atoms[i++] = display_info->atoms[NET_WM_ACTION_FULLSCREEN];
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE))
{
atoms[i++] = display_info->atoms[NET_WM_ACTION_MOVE];
}
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_RESIZE) &&
!((FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
&& (screen_info->params->borderless_maximize))))
{
atoms[i++] = display_info->atoms[NET_WM_ACTION_RESIZE];
}
if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
{
atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_HORZ];
atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_VERT];
}
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER))
{
atoms[i++] = display_info->atoms[NET_WM_ACTION_SHADE];
}
Olivier Fourdan
committed
}
if (CLIENT_CAN_HIDE_WINDOW (c))
{
atoms[i++] = display_info->atoms[NET_WM_ACTION_MINIMIZE];
}
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK))
Olivier Fourdan
committed
{
atoms[i++] = display_info->atoms[NET_WM_ACTION_CHANGE_DESKTOP];
atoms[i++] = display_info->atoms[NET_WM_ACTION_STICK];
Olivier Fourdan
committed
}
XChangeProperty (clientGetXDisplay (c), c->window, display_info->atoms[NET_WM_ALLOWED_ACTIONS],
XA_ATOM, 32, PropModeReplace, (unsigned char *) atoms, i);
Olivier Fourdan
committed
}
void
clientWindowType (Client * c)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
Olivier Fourdan
committed
g_return_if_fail (c != NULL);
TRACE ("entering clientWindowType");
TRACE ("type for client \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
Olivier Fourdan
committed
old_type = c->type;
c->initial_layer = c->win_layer;
if (c->type_atom != None)
{
if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_DESKTOP])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_desktop detected");
c->type = WINDOW_DESKTOP;
c->initial_layer = WIN_LAYER_DESKTOP;
c->win_state |= WIN_STATE_STICKY;
FLAG_SET (c->flags,
CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_STICKY |
CLIENT_FLAG_SKIP_TASKBAR);
XFWM_FLAG_HAS_RESIZE | XFWM_FLAG_HAS_MOVE |
XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE |
XFWM_FLAG_HAS_MENU | XFWM_FLAG_HAS_STICK |
XFWM_FLAG_HAS_BORDER);
Olivier Fourdan
committed
}
else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_DOCK])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_dock detected");
c->type = WINDOW_DOCK;
c->initial_layer = WIN_LAYER_DOCK;
Olivier Fourdan
committed
FLAG_SET (c->flags,
CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_STICKY |
CLIENT_FLAG_SKIP_TASKBAR);
FLAG_UNSET (c->xfwm_flags,
XFWM_FLAG_HAS_BORDER | XFWM_FLAG_HAS_MOVE |
XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE |
XFWM_FLAG_HAS_MENU);
Olivier Fourdan
committed
}
else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_TOOLBAR])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_toolbar detected");
c->type = WINDOW_TOOLBAR;
c->initial_layer = WIN_LAYER_NORMAL;
FLAG_SET (c->flags,
CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE);
Olivier Fourdan
committed
}
else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_MENU])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_menu detected");
c->type = WINDOW_MENU;
c->initial_layer = WIN_LAYER_NORMAL;
/* The policy here is unclear :
http://mail.gnome.org/archives/wm-spec-list/2002-May/msg00001.html
As it seems, GNOME and KDE don't treat menu the same way...
*/
FLAG_SET (c->flags,
CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE);
Olivier Fourdan
committed
}
else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_DIALOG])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_dialog detected");
c->type = WINDOW_DIALOG;
c->initial_layer = WIN_LAYER_NORMAL;
/* Treat DIALOG without transient_for set as transient for group */
if (c->transient_for == None)
{
c->transient_for = c->screen_info->xroot;
}
Olivier Fourdan
committed
}
else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_NORMAL])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_normal detected");
c->type = WINDOW_NORMAL;
c->initial_layer = WIN_LAYER_NORMAL;
}
else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_UTILITY])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_utility detected");
FLAG_SET (c->flags,
CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
Olivier Fourdan
committed
c->type = WINDOW_UTILITY;
c->initial_layer = WIN_LAYER_NORMAL;
/* Treat UTILITY without transient_for set as transient for group */
if (c->transient_for == None)
{
c->transient_for = c->screen_info->xroot;
}
Olivier Fourdan
committed
}
else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_SPLASH])
Olivier Fourdan
committed
{
TRACE ("atom net_wm_window_type_splash detected");
Olivier Fourdan
committed
c->type = WINDOW_SPLASHSCREEN;
Olivier Fourdan
committed
c->initial_layer = WIN_LAYER_NORMAL;
FLAG_SET (c->flags,
CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
FLAG_UNSET (c->xfwm_flags,
XFWM_FLAG_HAS_BORDER | XFWM_FLAG_HAS_HIDE |
XFWM_FLAG_HAS_MENU | XFWM_FLAG_HAS_MOVE |
XFWM_FLAG_HAS_RESIZE);
Olivier Fourdan
committed
}
}
else
{
TRACE ("no \"net\" atom detected");
c->type = UNSET;
c->initial_layer = c->win_layer;
}
Olivier Fourdan
committed
if (clientIsValidTransientOrModal (c))
Olivier Fourdan
committed
{
Client *c2;
TRACE ("Window \"%s\" is a transient or a modal", c->name);
c2 = clientGetHighestTransientOrModalFor (c);
if ((c2) && (c->initial_layer < c2->win_layer))
Olivier Fourdan
committed
{
c->initial_layer = c2->win_layer;
Olivier Fourdan
committed
TRACE ("Applied layer is %i", c->initial_layer);
}
Olivier Fourdan
committed
FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_HAS_HIDE);
Olivier Fourdan
committed
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
}
if ((old_type != c->type) || (c->initial_layer != c->win_layer))
{
TRACE ("setting layer %i", c->initial_layer);
clientSetNetState (c);
clientSetLayer (c, c->initial_layer);
}
}
void
clientUpdateAboveState (Client * c)
{
int layer;
g_return_if_fail (c != NULL);
TRACE ("entering clientUpdateAboveState");
TRACE ("Update above state for client \"%s\" (0x%lx)", c->name, c->window);
if (FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
{
layer = WIN_LAYER_ABOVE_DOCK;
}
else
{
layer = c->initial_layer;
}
clientSetNetState (c);
clientSetLayer (c, layer);
}
void
clientUpdateBelowState (Client * c)
{
int layer;
g_return_if_fail (c != NULL);
TRACE ("entering clientUpdateBelowState");
TRACE ("Update below state for client \"%s\" (0x%lx)", c->name, c->window);
if (FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
{
layer = WIN_LAYER_BELOW;
}
else
{
layer = c->initial_layer;
}
clientSetNetState (c);
clientSetLayer (c, layer);
}