Newer
Older
Olivier Fourdan
committed
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Olivier Fourdan
committed
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Olivier Fourdan
committed
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
xfwm4 - (c) 2002-2008 Olivier Fourdan
Olivier Fourdan
committed
*/
Olivier Fourdan
committed
#ifdef HAVE_CONFIG_H
Olivier Fourdan
committed
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <glib.h>
Olivier Fourdan
committed
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <libxfce4util/libxfce4util.h>
Olivier Fourdan
committed
#include "client.h"
Olivier Fourdan
committed
#include "compositor.h"
#include "display.h"
Olivier Fourdan
committed
#include "frame.h"
Olivier Fourdan
committed
#include "focus.h"
Olivier Fourdan
committed
#include "hints.h"
Olivier Fourdan
committed
#include "misc.h"
#include "netwm.h"
#include "screen.h"
Olivier Fourdan
committed
#include "stacking.h"
Olivier Fourdan
committed
#include "transients.h"
#include "workspaces.h"
Olivier Fourdan
committed
void
clientSetNetState (Client * c)
{
Olivier Fourdan
committed
Atom data[16];
Olivier Fourdan
committed
g_return_if_fail (c != NULL);
TRACE ("entering clientSetNetState");
TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
Olivier Fourdan
committed
i = 0;
if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
{
TRACE ("clientSetNetState : shaded");
data[i++] = display_info->atoms[NET_WM_STATE_SHADED];
Olivier Fourdan
committed
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
TRACE ("clientSetNetState : sticky");
data[i++] = display_info->atoms[NET_WM_STATE_STICKY];
Olivier Fourdan
committed
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL))
{
TRACE ("clientSetNetState : modal");
data[i++] = display_info->atoms[NET_WM_STATE_MODAL];
Olivier Fourdan
committed
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_PAGER))
{
TRACE ("clientSetNetState : skip_pager");
data[i++] = display_info->atoms[NET_WM_STATE_SKIP_PAGER];
Olivier Fourdan
committed
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_TASKBAR))
{
TRACE ("clientSetNetState : skip_taskbar");
data[i++] = display_info->atoms[NET_WM_STATE_SKIP_TASKBAR];
Olivier Fourdan
committed
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
{
TRACE ("clientSetNetState : maximize vert + horiz");
data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ];
data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT];
Olivier Fourdan
committed
}
else if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
{
TRACE ("clientSetNetState : maximize horiz");
data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ];
Olivier Fourdan
committed
}
else if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
{
TRACE ("clientSetNetState : vert");
data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT];
Olivier Fourdan
committed
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
{
TRACE ("clientSetNetState : fullscreen");
data[i++] = display_info->atoms[NET_WM_STATE_FULLSCREEN];
Olivier Fourdan
committed
}
else if (FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
{
TRACE ("clientSetNetState : above");
data[i++] = display_info->atoms[NET_WM_STATE_ABOVE];
Olivier Fourdan
committed
}
else if (FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
{
TRACE ("clientSetNetState : below");
data[i++] = display_info->atoms[NET_WM_STATE_BELOW];
Olivier Fourdan
committed
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
Olivier Fourdan
committed
{
TRACE ("clientSetNetState : hidden");
data[i++] = display_info->atoms[NET_WM_STATE_HIDDEN];
Olivier Fourdan
committed
}
Olivier Fourdan
committed
if (FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
{
TRACE ("clientSetNetState : demands_attention");
data[i++] = display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION];
XChangeProperty (display_info->dpy, c->window,
display_info->atoms[NET_WM_STATE], XA_ATOM, 32,
PropModeReplace, (unsigned char *) data, i);
Olivier Fourdan
committed
/*
We also set GNOME hint here for consistency and convenience,
Olivier Fourdan
committed
although the meaning of net_wm_state and win_state aren't the same.
*/
setHint (display_info, c->window, WIN_STATE, c->win_state);
Olivier Fourdan
committed
}
void
clientGetNetState (Client * c)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
int n_atoms;
Atom *atoms;
Olivier Fourdan
committed
g_return_if_fail (c != NULL);
TRACE ("entering clientGetNetState");
TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED))
{
if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
TRACE ("clientGetNetState : shaded from session management");
c->win_state |= WIN_STATE_SHADED;
FLAG_SET (c->flags, CLIENT_FLAG_SHADED);
if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
TRACE ("clientGetNetState : sticky from session management");
c->win_state |= WIN_STATE_STICKY;
FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
TRACE ("clientGetNetState : maximized horiz from session management");
c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;
FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
TRACE ("clientGetNetState : maximized vert from session management");
c->win_state |= WIN_STATE_MAXIMIZED_VERT;
FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
if (getAtomList (display_info, c->window, NET_WM_STATE, &atoms, &n_atoms))
Olivier Fourdan
committed
{
int i;
TRACE ("clientGetNetState: %i atoms detected", n_atoms);
i = 0;
while (i < n_atoms)
{
if ((atoms[i] == display_info->atoms[NET_WM_STATE_SHADED]))
Olivier Fourdan
committed
{
TRACE ("clientGetNetState : shaded");
c->win_state |= WIN_STATE_SHADED;
FLAG_SET (c->flags, CLIENT_FLAG_SHADED);
}
else if ((atoms[i] == display_info->atoms[NET_WM_STATE_STICKY]))
Olivier Fourdan
committed
{
TRACE ("clientGetNetState : sticky");
c->win_state |= WIN_STATE_STICKY;
FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
}
else if ((atoms[i] == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
Olivier Fourdan
committed
{
TRACE ("clientGetNetState : maximized horiz");
c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;
FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
}
else if ((atoms[i] == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
Olivier Fourdan
committed
{
TRACE ("clientGetNetState : maximized vert");
c->win_state |= WIN_STATE_MAXIMIZED_VERT;
FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
}
else if ((atoms[i] == display_info->atoms[NET_WM_STATE_FULLSCREEN]))
Olivier Fourdan
committed
{
if (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_ABOVE | CLIENT_FLAG_BELOW))
{
TRACE ("clientGetNetState : fullscreen");
FLAG_SET (c->flags, CLIENT_FLAG_FULLSCREEN);
}
else if ((atoms[i] == display_info->atoms[NET_WM_STATE_ABOVE]))
Olivier Fourdan
committed
{
if (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_FULLSCREEN | CLIENT_FLAG_BELOW))
{
TRACE ("clientGetNetState : above");
FLAG_SET (c->flags, CLIENT_FLAG_ABOVE);
Olivier Fourdan
committed
}
else if ((atoms[i] == display_info->atoms[NET_WM_STATE_BELOW]))
Olivier Fourdan
committed
{
if (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_ABOVE | CLIENT_FLAG_FULLSCREEN))
{
TRACE ("clientGetNetState : below");
FLAG_SET (c->flags, CLIENT_FLAG_BELOW);
Olivier Fourdan
committed
}
else if (atoms[i] == display_info->atoms[NET_WM_STATE_MODAL])
Olivier Fourdan
committed
{
TRACE ("clientGetNetState : modal");
FLAG_SET (c->flags, CLIENT_FLAG_STATE_MODAL);
}
else if (atoms[i] == display_info->atoms[NET_WM_STATE_SKIP_PAGER])
Olivier Fourdan
committed
{
TRACE ("clientGetNetState : skip_pager");
FLAG_SET (c->flags, CLIENT_FLAG_SKIP_PAGER);
}
else if (atoms[i] == display_info->atoms[NET_WM_STATE_SKIP_TASKBAR])
Olivier Fourdan
committed
{
TRACE ("clientGetNetState : skip_taskbar");
FLAG_SET (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
}
else if (atoms[i] == display_info->atoms[NET_WM_STATE_HIDDEN])
{
TRACE ("clientGetNetState : state_hidden");
FLAG_SET (c->flags, CLIENT_FLAG_ICONIFIED);
}
else if (atoms[i] == display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION])
{
TRACE ("clientGetNetState : demands_attention");
FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
}
Olivier Fourdan
committed
else
{
g_warning ("Unmanaged net_wm_state (window 0x%lx)", c->window);
Olivier Fourdan
committed
}
++i;
}
if (atoms)
{
XFree (atoms);
}
}
}
void
clientUpdateNetState (Client * c, XClientMessageEvent * ev)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
unsigned long action, mode;
Olivier Fourdan
committed
Atom first;
Atom second;
g_return_if_fail (c != NULL);
TRACE ("entering clientUpdateNetState");
TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
action = ev->data.l[0];
first = ev->data.l[1];
second = ev->data.l[2];
Olivier Fourdan
committed
if ((first == display_info->atoms[NET_WM_STATE_SHADED]) ||
(second == display_info->atoms[NET_WM_STATE_SHADED]))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
Olivier Fourdan
committed
{
clientShade (c);
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
Olivier Fourdan
committed
{
clientUnshade (c);
}
else if (action == NET_WM_STATE_TOGGLE)
{
clientToggleShaded (c);
}
}
if ((first == display_info->atoms[NET_WM_STATE_STICKY]) ||
(second == display_info->atoms[NET_WM_STATE_STICKY]))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
Olivier Fourdan
committed
{
clientStick (c, TRUE);
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
Olivier Fourdan
committed
{
clientUnstick (c, TRUE);
}
else if (action == NET_WM_STATE_TOGGLE)
{
clientToggleSticky (c, TRUE);
}
Olivier Fourdan
committed
}
}
if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
(first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
Olivier Fourdan
committed
{
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MAXIMIZE))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
Olivier Fourdan
committed
{
if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
Olivier Fourdan
committed
{
mode |= !FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) ? WIN_STATE_MAXIMIZED_HORIZ : 0;
Olivier Fourdan
committed
}
if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
Olivier Fourdan
committed
{
mode |= !FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) ? WIN_STATE_MAXIMIZED_VERT : 0;
Olivier Fourdan
committed
}
Olivier Fourdan
committed
clientToggleMaximized (c, mode, TRUE);
Olivier Fourdan
committed
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
Olivier Fourdan
committed
{
if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
Olivier Fourdan
committed
{
mode |= FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) ? WIN_STATE_MAXIMIZED_HORIZ : 0;
Olivier Fourdan
committed
}
if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
Olivier Fourdan
committed
{
mode |= FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) ? WIN_STATE_MAXIMIZED_VERT : 0;
Olivier Fourdan
committed
}
Olivier Fourdan
committed
clientToggleMaximized (c, mode, TRUE);
Olivier Fourdan
committed
}
else if (action == NET_WM_STATE_TOGGLE)
{
if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
Olivier Fourdan
committed
{
mode |= WIN_STATE_MAXIMIZED_HORIZ;
}
if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
(second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
Olivier Fourdan
committed
{
mode |= WIN_STATE_MAXIMIZED_VERT;
}
Olivier Fourdan
committed
clientToggleMaximized (c, mode, TRUE);
Olivier Fourdan
committed
}
}
}
if ((first == display_info->atoms[NET_WM_STATE_MODAL]) ||
(second == display_info->atoms[NET_WM_STATE_MODAL]))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL))
Olivier Fourdan
committed
{
FLAG_SET (c->flags, CLIENT_FLAG_STATE_MODAL);
clientSetNetState (c);
clientWindowType (c);
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL))
Olivier Fourdan
committed
{
FLAG_UNSET (c->flags, CLIENT_FLAG_STATE_MODAL);
clientSetNetState (c);
clientWindowType (c);
}
else if (action == NET_WM_STATE_TOGGLE)
{
FLAG_TOGGLE (c->flags, CLIENT_FLAG_STATE_MODAL);
clientSetNetState (c);
clientWindowType (c);
}
Olivier Fourdan
committed
}
if ((first == display_info->atoms[NET_WM_STATE_FULLSCREEN]) ||
(second == display_info->atoms[NET_WM_STATE_FULLSCREEN]))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
if (!clientIsValidTransientOrModal (c))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
Olivier Fourdan
committed
{
FLAG_SET (c->flags, CLIENT_FLAG_FULLSCREEN);
Olivier Fourdan
committed
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
Olivier Fourdan
committed
{
FLAG_UNSET (c->flags, CLIENT_FLAG_FULLSCREEN);
Olivier Fourdan
committed
}
else if (action == NET_WM_STATE_TOGGLE)
{
FLAG_TOGGLE (c->flags, CLIENT_FLAG_FULLSCREEN);
Olivier Fourdan
committed
}
}
}
if ((first == display_info->atoms[NET_WM_STATE_ABOVE]) ||
(second == display_info->atoms[NET_WM_STATE_ABOVE]))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
if (!FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
Olivier Fourdan
committed
{
FLAG_SET (c->flags, CLIENT_FLAG_ABOVE);
Olivier Fourdan
committed
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
Olivier Fourdan
committed
{
FLAG_UNSET (c->flags, CLIENT_FLAG_ABOVE);
Olivier Fourdan
committed
}
else if (action == NET_WM_STATE_TOGGLE)
{
FLAG_TOGGLE (c->flags, CLIENT_FLAG_ABOVE);
Olivier Fourdan
committed
}
}
}
if ((first == display_info->atoms[NET_WM_STATE_BELOW]) ||
(second == display_info->atoms[NET_WM_STATE_BELOW]))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
if (!FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
Olivier Fourdan
committed
{
FLAG_SET (c->flags, CLIENT_FLAG_BELOW);
Olivier Fourdan
committed
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
Olivier Fourdan
committed
{
FLAG_UNSET (c->flags, CLIENT_FLAG_BELOW);
Olivier Fourdan
committed
}
else if (action == NET_WM_STATE_TOGGLE)
{
FLAG_TOGGLE (c->flags, CLIENT_FLAG_BELOW);
Olivier Fourdan
committed
}
}
}
if ((first == display_info->atoms[NET_WM_STATE_SKIP_PAGER]) ||
(second == display_info->atoms[NET_WM_STATE_SKIP_PAGER]))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_PAGER))
Olivier Fourdan
committed
{
FLAG_SET (c->flags, CLIENT_FLAG_SKIP_PAGER);
clientSetNetState (c);
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_PAGER))
Olivier Fourdan
committed
{
FLAG_UNSET (c->flags, CLIENT_FLAG_SKIP_PAGER);
clientSetNetState (c);
}
else if (action == NET_WM_STATE_TOGGLE)
{
FLAG_TOGGLE (c->flags, CLIENT_FLAG_SKIP_PAGER);
clientSetNetState (c);
}
}
if ((first == display_info->atoms[NET_WM_STATE_SKIP_TASKBAR]) ||
(second == display_info->atoms[NET_WM_STATE_SKIP_TASKBAR]))
Olivier Fourdan
committed
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_TASKBAR))
Olivier Fourdan
committed
{
FLAG_SET (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
clientSetNetState (c);
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_TASKBAR))
Olivier Fourdan
committed
{
FLAG_UNSET (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
clientSetNetState (c);
}
else if (action == NET_WM_STATE_TOGGLE)
{
FLAG_TOGGLE (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
clientSetNetState (c);
}
Olivier Fourdan
committed
}
Olivier Fourdan
committed
if ((first == display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION]) ||
(second == display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION]))
{
if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
{
Olivier Fourdan
committed
/* Do not apply NET_WM_STATE_DEMANDS_ATTENTION if client is already focused */
if (c != clientGetFocusOrPending ())
{
FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
clientSetNetState (c);
}
Olivier Fourdan
committed
}
else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
{
FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
clientSetNetState (c);
}
else if (action == NET_WM_STATE_TOGGLE)
{
Olivier Fourdan
committed
/* Do not apply NET_WM_STATE_DEMANDS_ATTENTION if client is already focused */
if (c != clientGetFocusOrPending () || !FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
{
FLAG_TOGGLE (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
clientSetNetState (c);
}
Olivier Fourdan
committed
}
}
Olivier Fourdan
committed
}
void
clientNetMoveResize (Client * c, XClientMessageEvent * ev)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
unsigned int button_mask;
int x_root, y_root, dx, dy, action, button;
int corner;
gboolean resize; /* true == resize, false == move */
g_return_if_fail (c != NULL);
TRACE ("entering clientNetMoveResize");
TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
x_root = (int) ev->data.l[0];
y_root = (int) ev->data.l[1];
action = (int) ev->data.l[2];
button = (int) ev->data.l[3];
if (button == 0)
{
button_mask = getMouseXY (screen_info, c->window, &dx, &dy);
if (button_mask & Button1Mask)
{
button = Button1;
}
else if (button_mask & Button2Mask)
{
button = Button2;
}
else if (button_mask & Button3Mask)
{
button = Button3;
}
else
{
Olivier Fourdan
committed
/* Fallback */
button = Button1;
}
}
corner = CORNER_BOTTOM_RIGHT;
resize = TRUE;
event->xbutton.button = button;
event->xbutton.x_root = event->xkey.x_root = x_root;
event->xbutton.y_root = event->xkey.y_root = y_root;
event->xbutton.time = event->xkey.time = myDisplayGetCurrentTime (display_info);
switch (action)
{
/* Keyboard */
case NET_WM_MOVERESIZE_SIZE_KEYBOARD:
corner = CORNER_BOTTOM_RIGHT;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_MOVE_KEYBOARD:
resize = FALSE; /* Move */
break;
/* Sides */
case NET_WM_MOVERESIZE_SIZE_TOP:
corner = CORNER_COUNT + SIDE_TOP;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_SIZE_BOTTOM:
corner = CORNER_COUNT + SIDE_BOTTOM;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_SIZE_RIGHT:
corner = CORNER_COUNT + SIDE_RIGHT;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_SIZE_LEFT:
corner = CORNER_COUNT + SIDE_LEFT;
resize = TRUE; /* Resize */
break;
/* Corners */
case NET_WM_MOVERESIZE_SIZE_TOPLEFT:
corner = CORNER_TOP_LEFT;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
corner = CORNER_TOP_RIGHT;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
corner = CORNER_BOTTOM_LEFT;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
corner = CORNER_BOTTOM_RIGHT;
resize = TRUE; /* Resize */
break;
case NET_WM_MOVERESIZE_MOVE:
default:
resize = FALSE; /* Move */
break;
}
if (!FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
{
if (resize && FLAG_TEST_ALL (c->xfwm_flags, XFWM_FLAG_HAS_RESIZE | XFWM_FLAG_IS_RESIZABLE))
{
}
else if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE))
{
Olivier Fourdan
committed
void
clientUpdateFullscreenState (Client * c)
{
Olivier Fourdan
committed
ScreenInfo *screen_info;
DisplayInfo *display_info;
Olivier Fourdan
committed
XWindowChanges wc;
int layer;
g_return_if_fail (c != NULL);
TRACE ("entering clientUpdateFullscreenState");
TRACE ("Update fullscreen state for client \"%s\" (0x%lx)", c->name, c->window);
Olivier Fourdan
committed
screen_info = c->screen_info;
display_info = screen_info->display_info;
Olivier Fourdan
committed
if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
{
Olivier Fourdan
committed
GdkRectangle rect;
gint monitor_nbr;
Olivier Fourdan
committed
int cx, cy;
cx = frameX (c) + (frameWidth (c) / 2);
cy = frameY (c) + (frameHeight (c) / 2);
monitor_nbr = find_monitor_at_point (c->screen_info->gscr, cx, cy);
gdk_screen_get_monitor_geometry (c->screen_info->gscr, monitor_nbr, &rect);
Olivier Fourdan
committed
Olivier Fourdan
committed
c->fullscreen_old_x = c->x;
c->fullscreen_old_y = c->y;
c->fullscreen_old_width = c->width;
c->fullscreen_old_height = c->height;
c->fullscreen_old_layer = c->win_layer;
Olivier Fourdan
committed
wc.x = rect.x;
wc.y = rect.y;
wc.width = rect.width;
wc.height = rect.height;
Olivier Fourdan
committed
layer = WIN_LAYER_ABOVE_DOCK;
}
else
{
wc.x = c->fullscreen_old_x;
wc.y = c->fullscreen_old_y;
wc.width = c->fullscreen_old_width;
wc.height = c->fullscreen_old_height;
layer = c->fullscreen_old_layer;
}
clientSetNetState (c);
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
For some reason, the configure can generate EnterNotify events
on lower windows, causing a nasty race cond with apps trying to
grab focus in focus follow mouse mode. Grab the pointer to
avoid these effects
*/
Olivier Fourdan
committed
myScreenGrabPointer (c->screen_info, EnterWindowMask, None, myDisplayGetCurrentTime (display_info));
Olivier Fourdan
committed
clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, CFG_FORCE_REDRAW);
myScreenUngrabPointer (c->screen_info, myDisplayGetCurrentTime (display_info));
Olivier Fourdan
committed
}
else
{
c->x = wc.x;
c->y = wc.y;
c->height = wc.height;
c->width = wc.width;
}
clientSetLayer (c, layer);
/* Fullscreen has no decoration at all, update NET_FRAME_EXTENTS accordingly */
setNetFrameExtents (display_info,
c->window,
frameTop (c),
frameLeft (c),
frameRight (c),
frameBottom (c));
Olivier Fourdan
committed
}
void
clientGetNetWmType (Client * c)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
int n_atoms;
Atom *atoms;
Olivier Fourdan
committed
int i;
g_return_if_fail (c != NULL);
TRACE ("entering clientGetNetWmType");
TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
Olivier Fourdan
committed
n_atoms = 0;
atoms = NULL;
Olivier Fourdan
committed
c->type_atom = None;
Olivier Fourdan
committed
if (!getAtomList (display_info, c->window, NET_WM_WINDOW_TYPE, &atoms, &n_atoms))
Olivier Fourdan
committed
{
switch (c->win_layer)
{
case WIN_LAYER_DESKTOP:
c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_DESKTOP];
Olivier Fourdan
committed
break;
case WIN_LAYER_DOCK:
c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_DOCK];
Olivier Fourdan
committed
break;
case WIN_LAYER_NORMAL:
c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_NORMAL];
Olivier Fourdan
committed
break;
default:
Olivier Fourdan
committed
if (c->transient_for != None)
{
c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_DIALOG];
}
else
{
c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_NORMAL];
}
Olivier Fourdan
committed
break;
}
}
else
{
i = 0;
while (i < n_atoms)
{
if ((atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_DESKTOP]) ||
(atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_DOCK]) ||
(atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_TOOLBAR]) ||
(atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_MENU]) ||
(atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_DIALOG]) ||
(atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_NORMAL]) ||
(atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_UTILITY]) ||
(atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_SPLASH]))
Olivier Fourdan
committed
{
c->type_atom = atoms[i];
break;
}
++i;
}
if (atoms)
{
XFree (atoms);
}
}
clientWindowType (c);
}
void
clientGetInitialNetWmDesktop (Client * c)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
Client *c2;
long val;
Olivier Fourdan
committed
g_return_if_fail (c != NULL);
TRACE ("entering clientGetInitialNetWmDesktop");
TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
display_info = screen_info->display_info;
Olivier Fourdan
committed
if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED)
&& !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET))
Olivier Fourdan
committed
{
FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
Olivier Fourdan
committed
c->win_workspace = c->screen_info->current_ws;
Olivier Fourdan
committed
}
Olivier Fourdan
committed
if (getHint (display_info, c->window, NET_WM_DESKTOP, &val))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
TRACE ("atom net_wm_desktop detected");
if (val == (int) ALL_WORKSPACES)
Olivier Fourdan
committed
{
Olivier Fourdan
committed
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
TRACE ("atom net_wm_desktop specifies window \"%s\" is sticky", c->name);
FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
c->win_state |= WIN_STATE_STICKY;
Olivier Fourdan
committed
}
Olivier Fourdan
committed
c->win_workspace = c->screen_info->current_ws;
Olivier Fourdan
committed
}
Olivier Fourdan
committed
else
Olivier Fourdan
committed
{
Olivier Fourdan
committed
TRACE ("atom net_wm_desktop specifies window \"%s\" is on desk %i", c->name, (int) val);
Olivier Fourdan
committed
c->win_workspace = (int) val;
Olivier Fourdan
committed
}
FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
}
else if (getHint (display_info, c->window, WIN_WORKSPACE, &val))
{
TRACE ("atom win_workspace specifies window \"%s\" is on desk %i", c->name, (int) val);
c->win_workspace = (int) val;
FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
}
/* This is to make sure that transient are shown with their "ancestor" window */
if (!FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
c2 = clientGetTransient (c);
if (c2)
{
FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
Olivier Fourdan
committed
c->win_workspace = c2->win_workspace;
if (FLAG_TEST (c2->flags, CLIENT_FLAG_STICKY))
{
FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
c->win_state |= WIN_STATE_STICKY;
c->win_workspace = c->screen_info->current_ws;
}
Olivier Fourdan
committed
}
}
Olivier Fourdan
committed
TRACE ("initial desktop for window \"%s\" is %i", c->name, c->win_workspace);
if (c->win_workspace > c->screen_info->workspace_count - 1)
Olivier Fourdan
committed
{
TRACE ("value off limits, using %i instead", c->screen_info->workspace_count - 1);
c->win_workspace = c->screen_info->workspace_count - 1;
FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
Olivier Fourdan
committed
}
TRACE ("initial desktop for window \"%s\" is %i", c->name, c->win_workspace);
setHint (display_info, c->window, WIN_WORKSPACE, c->win_workspace);
Olivier Fourdan
committed
if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) ALL_WORKSPACES);
Olivier Fourdan
committed
}
else
{
setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) c->win_workspace);
Olivier Fourdan
committed
}
}
void
clientSetNetClientList (ScreenInfo * screen_info, Atom a, GList * list)
Olivier Fourdan
committed
{
Window *listw;
Window *index_dest;
GList *index_src;
gint size, i;
TRACE ("entering clientSetNetClientList");
size = g_list_length (list);
if (size < 1)
{
XDeleteProperty (myScreenGetXDisplay (screen_info), screen_info->xroot, a);
Olivier Fourdan
committed
}
Olivier Fourdan
committed
{
TRACE ("%i windows in list for %i clients", size, screen_info->client_count);
Olivier Fourdan
committed
for (i = 0, index_dest = listw, index_src = list; i < size;
i++, index_dest++, index_src = g_list_next (index_src))
{
Client *c = (Client *) index_src->data;
*index_dest = c->window;
}
XChangeProperty (myScreenGetXDisplay (screen_info), screen_info->xroot, a, XA_WINDOW, 32, PropModeReplace,
Olivier Fourdan
committed
(unsigned char *) listw, size);
Olivier Fourdan
committed
}
}
gboolean
clientValidateNetStrut (Client * c)
{
ScreenInfo *screen_info;
gboolean valid;
int max_value;
g_return_val_if_fail (c != NULL, TRUE);
TRACE ("entering clientValidateNetStrut for \"%s\" (0x%lx)", c->name, c->window);
screen_info = c->screen_info;
max_value = MIN (screen_info->width, screen_info->height) / 4;
valid = TRUE;
if (c->struts[STRUTS_TOP] > screen_info->height - screen_info->margins[STRUTS_BOTTOM])
c->struts[STRUTS_TOP] = screen_info->height - screen_info->margins[STRUTS_BOTTOM];
g_warning ("Top strut value for application window 0x%lx confined to %d", c->window, c->struts[STRUTS_TOP]);
valid = FALSE;
}
if (c->struts[STRUTS_BOTTOM] > screen_info->height - screen_info->margins[STRUTS_TOP])
{
c->struts[STRUTS_BOTTOM] = screen_info->height - screen_info->margins[STRUTS_TOP];
g_warning ("Bottom strut value for application window 0x%lx confined to %d", c->window, c->struts[STRUTS_BOTTOM]);
valid = FALSE;
}
if (c->struts[STRUTS_LEFT] > screen_info->width - screen_info->margins[STRUTS_RIGHT])
{
c->struts[STRUTS_LEFT] = screen_info->height - screen_info->margins[STRUTS_RIGHT];
g_warning ("Left strut value for application window 0x%lx confined to %d", c->window, c->struts[STRUTS_LEFT]);
valid = FALSE;
}
if (c->struts[STRUTS_RIGHT] > screen_info->width - screen_info->margins[STRUTS_LEFT])
{
c->struts[STRUTS_RIGHT] = screen_info->height - screen_info->margins[STRUTS_LEFT];
g_warning ("Right strut value for application window 0x%lx confined to %d", c->window, c->struts[STRUTS_RIGHT]);
valid = FALSE;
}
return valid;
}
gboolean
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);
}