gboolean myScreenGrabPointer (ScreenInfo *screen_info, gboolean owner_events, unsigned int event_mask, Cursor cursor, guint32 timestamp) { gboolean grab; g_return_val_if_fail (screen_info, FALSE); TRACE ("entering myScreenGrabPointer"); grab = TRUE; if (screen_info->pointer_grabs == 0) { grab = (XGrabPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, owner_events, event_mask, GrabModeAsync, GrabModeAsync, screen_info->xroot, cursor, (Time) timestamp) == GrabSuccess); } screen_info->pointer_grabs++; TRACE ("global pointer grabs %i", screen_info->pointer_grabs); return grab; }
void clientSetFocus (ScreenInfo *screen_info, Client *c, guint32 timestamp, unsigned short flags) { Client *c2; TRACE ("entering"); c2 = NULL; if ((c) && !(flags & FOCUS_IGNORE_MODAL)) { c2 = clientGetModalFor (c); if (c2) { c = c2; } } c2 = ((client_focus != c) ? client_focus : NULL); if ((c) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { TRACE ("setting focus to client \"%s\" (0x%lx) with timestamp %u", c->name, c->window, (unsigned int) timestamp); user_focus = c; if (FLAG_TEST(c->flags, CLIENT_FLAG_DEMANDS_ATTENTION)) { TRACE ("un-setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); clientSetNetState (c); } if ((c == client_focus) && !(flags & FOCUS_FORCE)) { TRACE ("client \"%s\" (0x%lx) is already focused, ignoring request", c->name, c->window); return; } if (!clientAcceptFocus (c)) { TRACE ("SKIP_FOCUS set for client \"%s\" (0x%lx)", c->name, c->window); return; } if (FLAG_TEST (c->wm_flags, WM_FLAG_INPUT) || !(screen_info->params->focus_hint)) { pending_focus = c; /* * When shaded, the client window is unmapped, so it can not be focused. * Instead, we focus the frame that is still mapped. */ if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)) { XSetInputFocus (myScreenGetXDisplay (screen_info), c->frame, RevertToPointerRoot, timestamp); } else { XSetInputFocus (myScreenGetXDisplay (screen_info), c->window, RevertToPointerRoot, timestamp); } } else if (flags & FOCUS_TRANSITION) { /* * If we are relying only on the client application to take focus, we need to set the focus * explicitely on our own fallback window otherwise there is a race condition between the * application and the window manager. If the application does not take focus before the * the previously focused window is unmapped (when iconifying or closing for example), the focus * will be reverted to the root window and focus transition will fail. */ clientFocusNone (screen_info, c2, timestamp); } if (FLAG_TEST(c->wm_flags, WM_FLAG_TAKEFOCUS)) { pending_focus = c; sendClientMessage (c->screen_info, c->window, WM_TAKE_FOCUS, timestamp); } } else { TRACE ("setting focus to none"); client_focus = NULL; clientFocusNone (screen_info, c2, timestamp); clientClearDelayedFocus (); } }
void xfwmWindowShow (xfwmWindow * win, int x, int y, int width, int height, gboolean refresh) { TRACE ("entering xfwmWindowShow"); if (!(win->window)) { return; } if ((width < 1) || (height < 1)) { xfwmWindowHide (win); return; } if (!(win->map)) { XMapWindow (myScreenGetXDisplay (win->screen_info), win->window); win->map = TRUE; } TRACE ("Showing XID 0x%lx", win->window); if (((x != win->x) || (y != win->y)) && ((width != win->width) || (height != win->height))) { XMoveResizeWindow (myScreenGetXDisplay (win->screen_info), win->window, x, y, (unsigned int) width, (unsigned int) height); win->x = x; win->y = y; win->width = width; win->height = height; } else if ((x != win->x) || (y != win->y)) { XMoveWindow (myScreenGetXDisplay (win->screen_info), win->window, x, y); if (refresh) { XClearWindow (myScreenGetXDisplay (win->screen_info), win->window); } win->x = x; win->y = y; } else if ((width != win->width) || (height != win->height)) { XResizeWindow (myScreenGetXDisplay (win->screen_info), win->window, (unsigned int) width, (unsigned int) height); win->width = width; win->height = height; } else if (refresh) { XClearWindow (myScreenGetXDisplay (win->screen_info), win->window); } }
static void wireframeDrawXlib (WireFrame *wireframe, int width, int height) { ScreenInfo *screen_info = wireframe->screen_info; wireframe->mapped = FALSE; XUnmapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow); XMoveResizeWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow, wireframe->x, wireframe->y, width, height); wireframe->width = width; wireframe->height = height; if ((wireframe->width > OUTLINE_WIDTH * 2) && (wireframe->height > OUTLINE_WIDTH * 2)) { XRectangle xrect; Region inner_xregion; Region outer_xregion; inner_xregion = XCreateRegion (); outer_xregion = XCreateRegion (); xrect.x = 0; xrect.y = 0; xrect.width = wireframe->width; xrect.height = wireframe->height; XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion); xrect.x += OUTLINE_WIDTH; xrect.y += OUTLINE_WIDTH; xrect.width -= OUTLINE_WIDTH * 2; xrect.height -= OUTLINE_WIDTH * 2; XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion); XSubtractRegion (outer_xregion, inner_xregion, outer_xregion); XShapeCombineRegion (myScreenGetXDisplay (screen_info), wireframe->xwindow, ShapeBounding, 0, 0, outer_xregion, ShapeSet); XDestroyRegion (outer_xregion); XDestroyRegion (inner_xregion); XMapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow); wireframe->mapped = TRUE; XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow, screen_info->box_gc, 0, 0, wireframe->width - 1, wireframe->height - 1); XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow, screen_info->box_gc, OUTLINE_WIDTH - 1, OUTLINE_WIDTH - 1, wireframe->width - 2 * (OUTLINE_WIDTH - 1) - 1, wireframe->height- 2 * (OUTLINE_WIDTH - 1) - 1); } else { /* Unset the shape */ XShapeCombineMask (myScreenGetXDisplay (screen_info), wireframe->xwindow, ShapeBounding, 0, 0, None, ShapeSet); XMapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow); wireframe->mapped = TRUE; XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow, screen_info->box_gc, 0, 0, wireframe->width - 1, wireframe->height - 1); } }
WireFrame * wireframeCreate (Client *c) { ScreenInfo *screen_info; WireFrame *wireframe; XSetWindowAttributes attrs; XVisualInfo xvisual_info; Visual *xvisual; int depth; g_return_val_if_fail (c != NULL, None); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); screen_info = c->screen_info; wireframe = g_new0 (WireFrame, 1); wireframe->screen_info = screen_info; wireframe->mapped = FALSE; wireframe->width = 0; wireframe->height = 0; wireframe->cr = NULL; wireframe->surface = NULL; wireframe->alpha = (compositorIsActive (screen_info) ? 0.5 : 1.0); if (compositorIsActive (screen_info) && XMatchVisualInfo (myScreenGetXDisplay (screen_info), screen_info->screen, 32, TrueColor, &xvisual_info)) { xvisual = xvisual_info.visual; depth = xvisual_info.depth; wireframe->xcolormap = XCreateColormap (myScreenGetXDisplay (screen_info), screen_info->xroot, xvisual, AllocNone); } else { xvisual = screen_info->visual; depth = screen_info->depth; wireframe->xcolormap = screen_info->cmap; } attrs.override_redirect = True; attrs.colormap = wireframe->xcolormap; attrs.background_pixel = BlackPixel (myScreenGetXDisplay (screen_info), screen_info->screen); attrs.border_pixel = BlackPixel (myScreenGetXDisplay (screen_info), screen_info->screen); wireframe->xwindow = XCreateWindow (myScreenGetXDisplay (screen_info), screen_info->xroot, frameExtentX (c), frameExtentY (c), frameExtentWidth (c), frameExtentHeight (c), 0, depth, InputOutput, xvisual, CWOverrideRedirect | CWColormap | CWBackPixel | CWBorderPixel, &attrs); if (compositorIsActive (screen_info)) { /* Cairo */ wireframeInitColor (wireframe); wireframe->surface = cairo_xlib_surface_create (myScreenGetXDisplay (screen_info), wireframe->xwindow, xvisual, frameExtentWidth (c), frameExtentHeight (c)); wireframe->cr = cairo_create (wireframe->surface); cairo_set_line_width (wireframe->cr, OUTLINE_WIDTH_CAIRO); cairo_set_line_join (wireframe->cr, CAIRO_LINE_JOIN_MITER); } wireframeUpdate (c, wireframe); return (wireframe); }
void workspaceSwitch (ScreenInfo *screen_info, gint new_ws, Client * c2, gboolean update_focus, guint32 timestamp) { DisplayInfo *display_info; Client *c, *new_focus; Client *previous; GList *list; Window dr, window; gint rx, ry, wx, wy; unsigned int mask; g_return_if_fail (screen_info != NULL); TRACE ("entering workspaceSwitch"); display_info = screen_info->display_info; if ((new_ws == (gint) screen_info->current_ws) && (screen_info->params->toggle_workspaces)) { new_ws = (gint) screen_info->previous_ws; } if (new_ws == (gint) screen_info->current_ws) { return; } if (screen_info->params->wrap_cycle) { if (new_ws > (gint) screen_info->workspace_count - 1) { new_ws = 0; } if (new_ws < 0) { new_ws = (gint) screen_info->workspace_count - 1; } } else if ((new_ws > (gint) screen_info->workspace_count - 1) || (new_ws < 0)) { return; } screen_info->previous_ws = screen_info->current_ws; screen_info->current_ws = new_ws; new_focus = NULL; previous = NULL; c = clientGetFocus (); if (c2) { clientSetWorkspace (c2, new_ws, FALSE); } if (c) { if (c->type & WINDOW_REGULAR_FOCUSABLE) { previous = c; } if (c2 == c) { new_focus = c2; } } /* First pass: Show, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { clientSetWorkspace (c, new_ws, TRUE); } else if (new_ws == (gint) c->win_workspace) { if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED) && !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientShow (c, FALSE); } } } } /* Second pass: Hide from bottom to top */ for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c = (Client *) list->data; if (new_ws != (gint) c->win_workspace) { if (c == previous) { FLAG_SET (previous->xfwm_flags, XFWM_FLAG_FOCUS); clientSetFocus (screen_info, NULL, timestamp, FOCUS_IGNORE_MODAL); } if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientWithdraw (c, new_ws, FALSE); } } } } /* Third pass: Check for focus, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if ((!new_focus) && (c == previous) && clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } else if (new_ws == (gint) c->win_workspace) { if ((!new_focus) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_FOCUS)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } } setNetCurrentDesktop (display_info, screen_info->xroot, new_ws); if (!(screen_info->params->click_to_focus)) { if (!(c2) && (XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, &dr, &window, &rx, &ry, &wx, &wy, &mask))) { c = clientAtPosition (screen_info, rx, ry, NULL); if (c) { new_focus = c; } } } if (update_focus) { if (new_focus) { if ((screen_info->params->click_to_focus) && (screen_info->params->raise_on_click)) { if (!(screen_info->params->raise_on_focus) && !clientIsTopMost (new_focus)) { clientRaise (new_focus, None); } } clientSetFocus (screen_info, new_focus, timestamp, FOCUS_SORT); } else { clientFocusTop (screen_info, WIN_LAYER_FULLSCREEN, timestamp); } } }