Newer
Older
handleButtonRelease (DisplayInfo *display_info, XButtonEvent * ev)
TRACE ("entering handleButtonRelease");
Olivier Fourdan
committed
#if CHECK_BUTTON_TIME
Olivier Fourdan
committed
/* Avoid treating the same event twice */
if (!check_button_time (ev))
{
TRACE ("ignoring ButtonRelease event because it has been already handled");
return;
}
Olivier Fourdan
committed
#endif
Olivier Fourdan
committed
/* Get the screen structure from the root of the event */
screen_info = myDisplayGetScreenFromRoot (display_info, ev->root);
if (!screen_info)
{
return;
}
Olivier Fourdan
committed
XSendEvent (display_info->dpy, screen_info->xfwm4_win, FALSE, SubstructureNotifyMask, (XEvent *) ev);
handleDestroyNotify (DisplayInfo *display_info, XDestroyWindowEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
TRACE ("entering handleDestroyNotify");
TRACE ("DestroyNotify on window (0x%lx)", ev->window);
#ifdef ENABLE_KDE_SYSTRAY_PROXY
screen_info = myDisplayGetScreenFromSystray (display_info, ev->window);
if (screen_info)
/* systray window is gone */
screen_info->systray = None;
#endif
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
TRACE ("DestroyNotify for \"%s\" (0x%lx)", c->name, c->window);
clientUnframe (c, FALSE);
}
}
handleMapRequest (DisplayInfo *display_info, XMapRequestEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
TRACE ("entering handleMapRequest");
TRACE ("MapRequest on window (0x%lx)", ev->window);
if (ev->window == None)
TRACE ("Mapping None ???");
return;
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
ScreenInfo *screen_info = c->screen_info;
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MAP_PENDING))
{
TRACE ("Ignoring MapRequest on window (0x%lx)", ev->window);
return;
}
Olivier Fourdan
committed
clientShow (c, TRUE);
Olivier Fourdan
committed
clientClearAllShowDesktop (screen_info);
if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY) ||
(c->win_workspace == screen_info->current_ws))
clientFrame (display_info, ev->window, FALSE);
handleMapNotify (DisplayInfo *display_info, XMapEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
TRACE ("MapNotify on window (0x%lx)", ev->window);
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
if (c)
{
TRACE ("MapNotify for \"%s\" (0x%lx)", c->name, c->window);
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MAP_PENDING))
FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_MAP_PENDING);
compositorMapWindow (display_info, c->frame);
else if (myDisplayGetScreenFromRoot (display_info, ev->event))
{
compositorMapWindow (display_info, ev->window);
handleUnmapNotify (DisplayInfo *display_info, XUnmapEvent * ev)
Client *c = NULL;
TRACE ("entering handleUnmapNotify");
TRACE ("UnmapNotify on window (0x%lx)", ev->window);
if (ev->from_configure)
{
TRACE ("Ignoring UnmapNotify caused by parent's resize");
screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
if (screen_info && (ev->event != ev->window) && (ev->event != screen_info->xroot || !ev->send_event))
TRACE ("handleUnmapNotify (): Event ignored");
return;
}
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
if (c)
{
TRACE ("UnmapNotify for \"%s\" (0x%lx)", c->name, c->window);
Olivier Fourdan
committed
TRACE ("ignore_unmap for \"%s\" is %i", c->name, c->ignore_unmap);
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MAP_PENDING))
* This UnmapNotify event is caused by reparenting
* so we just ignore it, so the window won't return
* to withdrawn state by mistake.
*/
TRACE ("Client \"%s\" is not mapped, event ignored", c->name);
compositorUnmapWindow (display_info, c->frame);
/*
* ICCCM spec states that a client wishing to switch
* to WithdrawnState should send a synthetic UnmapNotify
* with the event field set to root if the client window
* is already unmapped.
* Therefore, bypass the ignore_unmap counter and
* unframe the client.
*/
Olivier Fourdan
committed
if ((ev->event == screen_info->xroot) && (ev->send_event))
{
TRACE ("ICCCM UnmapNotify for \"%s\"", c->name);
clientUnframe (c, FALSE);
return;
}
if (c->ignore_unmap)
{
c->ignore_unmap--;
Olivier Fourdan
committed
TRACE ("ignore_unmap for \"%s\" is now %i",
c->name, c->ignore_unmap);
}
else
{
TRACE ("unmapping \"%s\" as ignore_unmap is %i",
c->name, c->ignore_unmap);
clientUnframe (c, FALSE);
compositorUnmapWindow (display_info, ev->window);
Olivier Fourdan
committed
static gboolean
update_screen_idle_cb (gpointer data)
{
ScreenInfo *screen_info = (ScreenInfo *) data;
DisplayInfo *display_info = screen_info->display_info;
setNetWorkarea (display_info, screen_info->xroot, screen_info->workspace_count,
gdk_screen_get_width (screen_info->gscr),
gdk_screen_get_height (screen_info->gscr),
screen_info->margins);
placeSidewalks (screen_info, screen_info->params->wrap_workspaces);
clientScreenResize (screen_info);
compositorUpdateScreenSize (screen_info);
Olivier Fourdan
committed
return FALSE;
}
handleConfigureNotify (DisplayInfo *display_info, XConfigureEvent * ev)
screen_info = myDisplayGetScreenFromRoot (display_info, ev->window);
if (!screen_info)
{
return;
}
if (display_info->have_xrandr)
XRRUpdateConfiguration ((XEvent *) ev);
#endif
}
else
Olivier Fourdan
committed
TRACE ("ConfigureNotify on the screen_info->xroot win (0x%lx)", ev->window);
Olivier Fourdan
committed
screen_info->xscreen->width = ev->width;
screen_info->xscreen->height = ev->height;
Olivier Fourdan
committed
/*
We need to use an idle function to update our screen layout to give gdk the
time to update its internal structures, ie let the current event be processed
by gdk otherwise the functions gdk_screen_get_width() and gdk_screen_get_height()
don't return accurate values...
*/
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, update_screen_idle_cb, screen_info, NULL);
handleConfigureRequest (DisplayInfo *display_info, XConfigureRequestEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
TRACE ("entering handleConfigureRequest");
TRACE ("ConfigureRequest on window (0x%lx)", ev->window);
while (XCheckTypedWindowEvent (display_info->dpy, ev->window, ConfigureRequest, &otherEvent))
/* Update the display time */
myDisplayUpdateCurentTime (display_info, &otherEvent);
if (otherEvent.xconfigurerequest.value_mask == ev->value_mask)
{
ev = &otherEvent.xconfigurerequest;
}
else
{
XPutBackEvent (display_info->dpy, &otherEvent);
wc.x = ev->x;
wc.y = ev->y;
wc.width = ev->width;
wc.height = ev->height;
wc.sibling = ev->above;
wc.stack_mode = ev->detail;
wc.border_width = ev->border_width;
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
if (!c)
{
/* Some app tend or try to manipulate the wm frame to achieve fullscreen mode */
c = myDisplayGetClientFromWindow (display_info, ev->window, FRAME);
TRACE ("client %s (0x%lx) is attempting to manipulate its frame!", c->name, c->window);
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
if (ev->value_mask & CWX)
{
wc.x += frameLeft (c);
}
if (ev->value_mask & CWY)
{
wc.y += frameTop (c);
}
if (ev->value_mask & CWWidth)
{
wc.width -= frameLeft (c) + frameRight (c);
}
if (ev->value_mask & CWHeight)
{
wc.height -= frameTop (c) + frameBottom (c);
}
/* We don't allow changing stacking order by accessing the frame
window because that would break the layer management in xfwm4
*/
ev->value_mask &= ~(CWSibling | CWStackMode);
}
}
if (c)
{
gboolean constrained = FALSE;
TRACE ("handleConfigureRequest managed window \"%s\" (0x%lx)", c->name, c->window);
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING))
{
/* Sorry, but it's not the right time for configure request */
return;
}
if (c->type == WINDOW_DESKTOP)
{
/* Ignore stacking request for DESKTOP windows */
ev->value_mask &= ~(CWSibling | CWStackMode);
}
clientCoordGravitate (c, APPLY, &wc.x, &wc.y);
if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
Olivier Fourdan
committed
GdkRectangle rect;
gint monitor_nbr;
int cx, cy;
/* size request from fullscreen windows get fullscreen */
cx = frameX (c) + (frameWidth (c) / 2);
cy = frameY (c) + (frameHeight (c) / 2);
monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
Olivier Fourdan
committed
wc.x = rect.x;
wc.y = rect.y;
wc.width = rect.width;
wc.height = rect.height;
/* Clean up buggy requests that set all flags */
if ((ev->value_mask & CWX) && (wc.x == c->x))
{
ev->value_mask &= ~CWX;
}
if ((ev->value_mask & CWY) && (wc.y == c->y))
{
ev->value_mask &= ~CWY;
}
if ((ev->value_mask & CWWidth) && (wc.width == c->width))
{
ev->value_mask &= ~CWWidth;
}
if ((ev->value_mask & CWHeight) && (wc.height == c->height))
{
ev->value_mask &= ~CWHeight;
}
/* Still a move/resize after cleanup? */
if (ev->value_mask & (CWX | CWY | CWWidth | CWHeight))
{
if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
{
clientRemoveMaximizeFlag (c);
}
constrained = TRUE;
}
if (ev->value_mask & CWStackMode)
{
Olivier Fourdan
committed
clientPassGrabMouseButton (NULL);
Olivier Fourdan
committed
}
Olivier Fourdan
committed
#if 0
/* Let's say that if the client performs a XRaiseWindow, we show the window if hidden */
if ((ev->value_mask & CWStackMode) && (wc.stack_mode == Above))
{
if ((c->win_workspace == screen_info->current_ws) ||
(FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)))
if (FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
{
clientShow (c, TRUE);
Olivier Fourdan
committed
clientClearAllShowDesktop (screen_info);
Olivier Fourdan
committed
#endif
clientConfigure (c, &wc, ev->value_mask, (constrained ? CFG_CONSTRAINED : 0) | CFG_REQUEST);
TRACE ("unmanaged configure request for win 0x%lx", ev->window);
XConfigureWindow (display_info->dpy, ev->window, ev->value_mask, &wc);
handleEnterNotify (DisplayInfo *display_info, XCrossingEvent * ev)
static Time lastresist = (Time) 0;
Olivier Fourdan
committed
Client *c = NULL;
Olivier Fourdan
committed
ScreenInfo *screen_info = NULL;
gboolean warp_pointer = FALSE;
TRACE ("entering handleEnterNotify");
if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab)
|| (ev->detail > NotifyNonlinearVirtual))
/* We're not interested in such notifications */
return;
TRACE ("EnterNotify on window (0x%lx)", ev->window);
c = myDisplayGetClientFromWindow (display_info, ev->window, FRAME);
if (c)
screen_info = c->screen_info;
if (!(screen_info->params->click_to_focus) && clientAcceptFocus (c))
TRACE ("EnterNotify window is \"%s\"", c->name);
if (!(c->type & (WINDOW_DOCK | WINDOW_DESKTOP)))
Olivier Fourdan
committed
{
clientSetFocus (c->screen_info, c, ev->time, NO_FOCUS_FLAG);
Olivier Fourdan
committed
}
Olivier Fourdan
committed
/* No need to process the event any further */
return;
}
/* The event was not for a client window */
if (display_info->nb_screens > 1)
{
/* Wrap workspace/wrap windows is disabled with multiscreen */
return;
}
Olivier Fourdan
committed
/* Get the screen structure from the root of the event */
screen_info = myDisplayGetScreenFromRoot (display_info, ev->root);
if (!screen_info)
{
return;
}
if (screen_info->workspace_count && screen_info->params->wrap_workspaces
&& screen_info->params->wrap_resistance)
{
int msx, msy, maxx, maxy;
int rx, ry;
msx = ev->x_root;
msy = ev->y_root;
maxx = gdk_screen_get_width (screen_info->gscr) - 1;
maxy = gdk_screen_get_height (screen_info->gscr) - 1;
warp_pointer = FALSE;
if ((msx == 0) || (msx == maxx))
Olivier Fourdan
committed
{
if ((ev->time - lastresist) > 250) /* ms */
{
edge_scroll_x = 0;
}
else
{
edge_scroll_x++;
}
if (msx == 0)
{
lastresist = ev->time;
}
if ((msy == 0) || (msy == maxy))
{
if ((ev->time - lastresist) > 250) /* ms */
{
edge_scroll_y = 0;
}
else
{
edge_scroll_y++;
}
if (msy == 0)
{
}
else
{
lastresist = ev->time;
}
Olivier Fourdan
committed
if (edge_scroll_x > screen_info->params->wrap_resistance)
{
Olivier Fourdan
committed
edge_scroll_x = 0;
Olivier Fourdan
committed
{
if (workspaceMove (screen_info, 0, -1, NULL))
{
Olivier Fourdan
committed
}
Olivier Fourdan
committed
{
if (workspaceMove (screen_info, 0, 1, NULL))
{
Olivier Fourdan
committed
}
warp_pointer = TRUE;
}
if (edge_scroll_y > screen_info->params->wrap_resistance)
{
edge_scroll_y = 0;
Olivier Fourdan
committed
{
if (workspaceMove (screen_info, -1, 0, NULL))
{
}
}
{
if (workspaceMove (screen_info, 1, 0, NULL))
{
}
}
warp_pointer = TRUE;
}
if (warp_pointer)
{
XWarpPointer (display_info->dpy, None, None, 0, 0, 0, 0, rx, ry);
XFlush (display_info->dpy);
Olivier Fourdan
committed
}
handleLeaveNotify (DisplayInfo *display_info, XCrossingEvent * ev)
Olivier Fourdan
committed
{
TRACE ("entering handleLeaveNotify");
Olivier Fourdan
committed
}
handleFocusIn (DisplayInfo *display_info, XFocusChangeEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
Client *last_raised = NULL;
TRACE ("entering handleFocusIn");
Olivier Fourdan
committed
TRACE ("handleFocusIn (0x%lx) mode = %s",
ev->window,
(ev->mode == NotifyNormal) ?
"NotifyNormal" :
(ev->mode == NotifyWhileGrabbed) ?
"NotifyWhileGrabbed" :
"(unknown)");
Olivier Fourdan
committed
TRACE ("handleFocusIn (0x%lx) detail = %s",
ev->window,
(ev->detail == NotifyAncestor) ?
"NotifyAncestor" :
(ev->detail == NotifyVirtual) ?
"NotifyVirtual" :
(ev->detail == NotifyInferior) ?
"NotifyInferior" :
(ev->detail == NotifyNonlinear) ?
"NotifyNonlinear" :
(ev->detail == NotifyNonlinearVirtual) ?
"NotifyNonlinearVirtual" :
(ev->detail == NotifyPointer) ?
"NotifyPointer" :
(ev->detail == NotifyPointerRoot) ?
"NotifyPointerRoot" :
(ev->detail == NotifyDetailNone) ?
"NotifyDetailNone" :
"(unknown)");
screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
if (screen_info && (ev->window == screen_info->xroot) && (ev->mode == NotifyNormal) &&
Olivier Fourdan
committed
(ev->detail == NotifyDetailNone))
{
/* Handle focus transition to root (means that an unknown
window has vanished and the focus is returned to the root
Olivier Fourdan
committed
*/
c = clientGetFocus ();
if (c)
{
clientSetFocus (c->screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_FORCE);
Olivier Fourdan
committed
}
return;
}
if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab) ||
Olivier Fourdan
committed
(ev->detail > NotifyNonlinearVirtual))
{
/* We're not interested in such notifications */
return;
}
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
TRACE ("FocusIn on window (0x%lx)", ev->window);
TRACE ("focus set to \"%s\" (0x%lx)", c->name, c->window);
clientUpdateFocus (screen_info, c, FOCUS_SORT);
last_raised = clientGetLastRaise (screen_info);
if ((screen_info->params->click_to_focus) &&
(screen_info->params->raise_on_click) &&
(last_raised != NULL) && (c != last_raised))
Olivier Fourdan
committed
clientRaise (c, None);
if (screen_info->params->raise_on_focus)
handleFocusOut (DisplayInfo *display_info, XFocusChangeEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
Olivier Fourdan
committed
TRACE ("entering handleFocusOut");
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
TRACE ("handleFocusOut (0x%lx) mode = %s",
ev->window,
(ev->mode == NotifyNormal) ?
"NotifyNormal" :
(ev->mode == NotifyWhileGrabbed) ?
"NotifyWhileGrabbed" :
"(unknown)");
TRACE ("handleFocusOut (0x%lx) detail = %s",
ev->window,
(ev->detail == NotifyAncestor) ?
"NotifyAncestor" :
(ev->detail == NotifyVirtual) ?
"NotifyVirtual" :
(ev->detail == NotifyInferior) ?
"NotifyInferior" :
(ev->detail == NotifyNonlinear) ?
"NotifyNonlinear" :
(ev->detail == NotifyNonlinearVirtual) ?
"NotifyNonlinearVirtual" :
(ev->detail == NotifyPointer) ?
"NotifyPointer" :
(ev->detail == NotifyPointerRoot) ?
"NotifyPointerRoot" :
(ev->detail == NotifyDetailNone) ?
"NotifyDetailNone" :
"(unknown)");
if ((ev->mode == NotifyNormal)
&& ((ev->detail == NotifyNonlinear)
|| (ev->detail == NotifyNonlinearVirtual)))
Olivier Fourdan
committed
{
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
TRACE ("FocusOut on window (0x%lx)", ev->window);
Olivier Fourdan
committed
if ((c) && (c == clientGetFocus ()))
{
TRACE ("focus lost from \"%s\" (0x%lx)", c->name, c->window);
Olivier Fourdan
committed
clientPassGrabMouseButton (NULL);
clientUpdateFocus (c->screen_info, NULL, NO_FOCUS_FLAG);
/* Clear timeout */
clear_timeout ();
}
Olivier Fourdan
committed
}
handlePropertyNotify (DisplayInfo *display_info, XPropertyEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
TRACE ("entering handlePropertyNotify");
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
if (c)
{
screen_info = c->screen_info;
if (ev->atom == XA_WM_NORMAL_HINTS)
{
TRACE ("client \"%s\" (0x%lx) has received a XA_WM_NORMAL_HINTS notify", c->name, c->window);
else if ((ev->atom == XA_WM_NAME) ||
(ev->atom == display_info->atoms[NET_WM_NAME]) ||
(ev->atom == display_info->atoms[WM_CLIENT_MACHINE]))
TRACE ("client \"%s\" (0x%lx) has received a XA_WM_NAME/NET_WM_NAME/WM_CLIENT_MACHINE notify", c->name, c->window);
if (c->name)
{
Olivier Fourdan
committed
g_free (c->name);
getWindowName (display_info, c->window, &c->name);
FLAG_SET (c->flags, CLIENT_FLAG_NAME_CHANGED);
frameDraw (c, TRUE, FALSE);
}
else if (ev->atom == display_info->atoms[MOTIF_WM_HINTS])
TRACE ("client \"%s\" (0x%lx) has received a motif_wm_hints notify", c->name, c->window);
}
else if (ev->atom == XA_WM_HINTS)
{
TRACE ("client \"%s\" (0x%lx) has received a XA_WM_HINTS notify", c->name, c->window);
c->wmhints = XGetWMHints (display_info->dpy, c->window);
if (c->wmhints)
{
if (c->wmhints->flags & WindowGroupHint)
{
c->group_leader = c->wmhints->window_group;
}
if ((c->wmhints->flags & IconPixmapHint) && (screen_info->params->show_app_icon))
{
clientUpdateIcon (c);
frameDraw (c, TRUE, FALSE);
}
else if (ev->atom == display_info->atoms[WM_PROTOCOLS])
TRACE ("client \"%s\" (0x%lx) has received a wm_protocols notify", c->name, c->window);
else if (ev->atom == display_info->atoms[WM_TRANSIENT_FOR])
{
Window w;
TRACE ("client \"%s\" (0x%lx) has received a wm_transient_for notify", c->name, c->window);
getTransientFor (display_info, c->screen_info->xroot, c->window, &w);
if (clientCheckTransientWindow (c, w))
{
c->transient_for = w;
Olivier Fourdan
committed
clientRaise (c, w);
}
}
else if (ev->atom == display_info->atoms[WIN_HINTS])
TRACE ("client \"%s\" (0x%lx) has received a win_hints notify", c->name, c->window);
getHint (display_info, c->window, WIN_HINTS, (long *) &c->win_hints);
else if (ev->atom == display_info->atoms[NET_WM_WINDOW_TYPE])
TRACE ("client \"%s\" (0x%lx) has received a net_wm_window_type notify", c->name, c->window);
clientGetNetWmType (c);
frameDraw (c, TRUE, FALSE);
}
else if ((ev->atom == display_info->atoms[NET_WM_STRUT]) ||
(ev->atom == display_info->atoms[NET_WM_STRUT_PARTIAL]))
TRACE ("client \"%s\" (0x%lx) has received a net_wm_strut notify", c->name, c->window);
clientGetNetStruts (c);
}
else if (ev->atom == display_info->atoms[WM_COLORMAP_WINDOWS])
TRACE ("client \"%s\" (0x%lx) has received a wm_colormap_windows notify", c->name, c->window);
clientUpdateColormaps (c);
if (c == clientGetFocus ())
{
clientInstallColormaps (c);
}
}
else if (ev->atom == display_info->atoms[NET_WM_USER_TIME])
Olivier Fourdan
committed
{
TRACE ("client \"%s\" (0x%lx) has received a net_wm_user_time notify", c->name, c->window);
if (getNetWMUserTime (display_info, c->window, &c->user_time))
Olivier Fourdan
committed
{
Olivier Fourdan
committed
FLAG_SET (c->flags, CLIENT_FLAG_HAS_USER_TIME);
Olivier Fourdan
committed
}
Olivier Fourdan
committed
}
else if (ev->atom == display_info->atoms[NET_WM_WINDOW_OPACITY])
TRACE ("client \"%s\" (0x%lx) has received a net_wm_opacity notify", c->name, c->window);
if (!getOpacity (display_info, c->window, &c->opacity))
compositorWindowSetOpacity (display_info, c->frame, c->opacity);
else if ((screen_info->params->show_app_icon) &&
((ev->atom == display_info->atoms[NET_WM_ICON]) ||
(ev->atom == display_info->atoms[KWM_WIN_ICON])))
{
clientUpdateIcon (c);
frameDraw (c, TRUE, FALSE);
}
#ifdef HAVE_STARTUP_NOTIFICATION
else if (ev->atom == display_info->atoms[NET_STARTUP_ID])
{
if (c->startup_id)
{
Olivier Fourdan
committed
g_free (c->startup_id);
c->startup_id = NULL;
}
getWindowStartupId (display_info, c->window, &c->startup_id);
#endif
return;
}
screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
if (!screen_info)
{
return;
if (ev->atom == display_info->atoms[NET_DESKTOP_NAMES])
{
Olivier Fourdan
committed
gchar **names;
int items;
TRACE ("root has received a net_desktop_names notify");
if (getUTF8StringList (display_info, screen_info->xroot, NET_DESKTOP_NAMES, &names, &items))
{
workspaceSetNames (screen_info, names, items);
}
}
else if (ev->atom == display_info->atoms[GNOME_PANEL_DESKTOP_AREA])
TRACE ("root has received a gnome_panel_desktop_area notify");
getGnomeDesktopMargins (display_info, screen_info->xroot, screen_info->gnome_margins);
else if (ev->atom == display_info->atoms[NET_DESKTOP_LAYOUT])
Olivier Fourdan
committed
{
TRACE ("root has received a net_desktop_layout notify");
getDesktopLayout(display_info, screen_info->xroot, screen_info->workspace_count, &screen_info->desktop_layout);
Olivier Fourdan
committed
placeSidewalks(screen_info, screen_info->params->wrap_workspaces);
Olivier Fourdan
committed
}
handleClientMessage (DisplayInfo *display_info, XClientMessageEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
TRACE ("entering handleClientMessage");
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
if (c)
{
if ((ev->message_type == display_info->atoms[WM_CHANGE_STATE]) && (ev->format == 32) && (ev->data.l[0] == IconicState))
TRACE ("client \"%s\" (0x%lx) has received a wm_change_state event", c->name, c->window);
if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED) && CLIENT_CAN_HIDE_WINDOW (c))
{
clientHide (c, c->win_workspace, TRUE);
}
}
else if ((ev->message_type == display_info->atoms[WIN_STATE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a win_state event", c->name, c->window);
clientUpdateWinState (c, ev);
}
else if ((ev->message_type == display_info->atoms[WIN_LAYER]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a win_layer event", c->name, c->window);
if ((ev->data.l[0] != c->win_layer) && !is_transient)
{
clientSetLayer (c, ev->data.l[0]);
}
}
else if ((ev->message_type == display_info->atoms[WIN_WORKSPACE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a win_workspace event", c->name, c->window);
if ((ev->data.l[0] != c->win_workspace) && !is_transient)
{
clientSetWorkspace (c, ev->data.l[0], TRUE);
}
}
else if ((ev->message_type == display_info->atoms[NET_WM_DESKTOP]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_wm_desktop event", c->name, c->window);
{
if (ev->data.l[0] == ALL_WORKSPACES)
{
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
clientStick (c, TRUE);
frameDraw (c, FALSE, FALSE);
}
}
else
{
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
clientUnstick (c, TRUE);
frameDraw (c, FALSE, FALSE);
}
if (ev->data.l[0] != c->win_workspace)
{
clientSetWorkspace (c, ev->data.l[0], TRUE);
}
}
}
}
else if ((ev->message_type == display_info->atoms[NET_CLOSE_WINDOW]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_close_window event", c->name, c->window);
clientClose (c);
}
else if ((ev->message_type == display_info->atoms[NET_WM_STATE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_wm_state event", c->name, c->window);
clientUpdateNetState (c, ev);
}
else if ((ev->message_type == display_info->atoms[NET_WM_MOVERESIZE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_wm_moveresize event", c->name, c->window);
g_warning ("Operation not supported (yet)");
else if ((ev->message_type == display_info->atoms[NET_ACTIVE_WINDOW]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_active_window event", c->name, c->window);
Time current = myDisplayGetCurrentTime (screen_info->display_info);
Time ev_time = (Time) ev->data.l[1];
/* We are simply ignoring XServer time wraparound here */
TRACE ("Time of event received is %u, current XServer time is %u", (unsigned int) ev_time, (unsigned int) current);
Olivier Fourdan
committed
if ((ev_time != (Time) 0) && (ev_time < current))
{
FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
clientSetNetState (c);
}
else
{
clientSetWorkspace (c, screen_info->current_ws, TRUE);
clientShow (c, TRUE);
Olivier Fourdan
committed
clientClearAllShowDesktop (screen_info);
clientRaise (c, None);
clientSetFocus (screen_info, c, (Time) ev_time, NO_FOCUS_FLAG);
}
clientSetWorkspace (c, screen_info->current_ws, TRUE);
clientShow (c, TRUE);
Olivier Fourdan
committed
clientClearAllShowDesktop (screen_info);
clientSetFocus (screen_info, c, CurrentTime, NO_FOCUS_FLAG);
}
else if (ev->message_type == display_info->atoms[NET_REQUEST_FRAME_EXTENTS])
Olivier Fourdan
committed
{
TRACE ("client \"%s\" (0x%lx) has received a net_request_frame_extents event", c->name, c->window);
setNetFrameExtents (display_info, c->window, frameTop (c), frameLeft (c),
frameRight (c), frameBottom (c));
Olivier Fourdan
committed
}
screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
if (!screen_info)
{
return;
}
if (((ev->message_type == display_info->atoms[WIN_WORKSPACE]) ||
(ev->message_type == display_info->atoms[NET_CURRENT_DESKTOP])) && (ev->format == 32))