static gboolean myScreenSetWMAtom (ScreenInfo *screen_info, gboolean replace_wm) { const char *wm_name; gchar selection[32]; gchar *display_name; gulong wait, timeout; DisplayInfo *display_info; XSetWindowAttributes attrs; Window current_wm; XEvent event; Atom wm_sn_atom; g_return_val_if_fail (screen_info, FALSE); g_return_val_if_fail (screen_info->display_info, FALSE); TRACE ("entering myScreenReplaceWM"); display_info = screen_info->display_info; g_snprintf (selection, sizeof (selection), "WM_S%d", screen_info->screen); wm_sn_atom = XInternAtom (display_info->dpy, selection, FALSE); display_name = gdk_screen_make_display_name (screen_info->gscr); wm_name = gdk_x11_screen_get_window_manager_name (screen_info->gscr); XSync (display_info->dpy, FALSE); current_wm = XGetSelectionOwner (display_info->dpy, wm_sn_atom); if (current_wm) { if (!replace_wm) { g_message ("Another Window Manager (%s) is already running on screen %s", wm_name, display_name); g_message ("To replace the current window manager, try \"--replace\""); g_free (display_name); return FALSE; } gdk_error_trap_push (); attrs.event_mask = StructureNotifyMask; XChangeWindowAttributes (display_info->dpy, current_wm, CWEventMask, &attrs); if (gdk_error_trap_pop ()) { current_wm = None; } } if (!setXAtomManagerOwner (display_info, wm_sn_atom, screen_info->xroot, screen_info->xfwm4_win)) { g_warning ("Cannot acquire window manager selection on screen %s", display_name); g_free (display_name); return FALSE; } /* Waiting for previous window manager to exit */ if (current_wm) { g_print ("Waiting for current window manager (%s) on screen %s to exit:", wm_name, display_name); wait = 0; timeout = WM_EXITING_TIMEOUT * G_USEC_PER_SEC; while (wait < timeout) { if (XCheckWindowEvent (display_info->dpy, current_wm, StructureNotifyMask, &event) && (event.type == DestroyNotify)) { break; } g_usleep(G_USEC_PER_SEC / 10); wait += G_USEC_PER_SEC / 10; if (wait % G_USEC_PER_SEC == 0) { g_print ("."); } } if (wait >= timeout) { g_print(" Failed\n"); g_warning("Previous window manager (%s) on screen %s is not exiting", wm_name, display_name); g_free (display_name); return FALSE; } g_print(" Done\n"); } g_free (display_name); return TRUE; }
static VALUE rg_s_error_trap_pop(VALUE self) { gdk_error_trap_pop(); return self; }
static void sn_error_trap_pop(SnDisplay *display, Display *xdisplay) { gdk_error_trap_pop(); }
GtkWidget * na_tray_child_new (GdkScreen *screen, Window icon_window) { XWindowAttributes window_attributes; Display *xdisplay; NaTrayChild *child; GdkVisual *visual; gboolean visual_has_alpha; GdkColormap *colormap; gboolean new_colormap; int result; g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); g_return_val_if_fail (icon_window != None, NULL); xdisplay = GDK_SCREEN_XDISPLAY (screen); /* We need to determine the visual of the window we are embedding and create * the socket in the same visual. */ gdk_error_trap_push (); result = XGetWindowAttributes (xdisplay, icon_window, &window_attributes); gdk_error_trap_pop (); if (!result) /* Window already gone */ return NULL; visual = gdk_x11_screen_lookup_visual (screen, window_attributes.visual->visualid); if (!visual) /* Icon window is on another screen? */ return NULL; new_colormap = FALSE; if (visual == gdk_screen_get_rgb_visual (screen)) colormap = gdk_screen_get_rgb_colormap (screen); else if (visual == gdk_screen_get_rgba_visual (screen)) colormap = gdk_screen_get_rgba_colormap (screen); else if (visual == gdk_screen_get_system_visual (screen)) colormap = gdk_screen_get_system_colormap (screen); else { colormap = gdk_colormap_new (visual, FALSE); new_colormap = TRUE; } child = g_object_new (NA_TYPE_TRAY_CHILD, NULL); child->icon_window = icon_window; gtk_widget_set_colormap (GTK_WIDGET (child), colormap); /* We have alpha if the visual has something other than red, green, * and blue */ visual_has_alpha = visual->red_prec + visual->blue_prec + visual->green_prec < visual->depth; child->has_alpha = (visual_has_alpha && gdk_display_supports_composite (gdk_screen_get_display (screen))); child->composited = child->has_alpha; if (new_colormap) g_object_unref (colormap); return GTK_WIDGET (child); }
int meta_error_trap_pop_with_return (MetaDisplay *display, gboolean last_request_was_roundtrip) { return gdk_error_trap_pop (); }
gboolean update_window_decoration_size (WnckWindow *win) { decor_t *d; GdkPixmap *pixmap, *buffer_pixmap = NULL; Picture picture; Display *xdisplay; XRenderPictFormat *format; if (win == NULL) return FALSE; d = g_object_get_data (G_OBJECT (win), "decor"); if (!d->decorated) return FALSE; xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); gdk_error_trap_push (); /* Get the correct depth for the frame window in reparenting mode, otherwise * enforce 32 */ if (d->frame_window) pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgb); else pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgba); gdk_flush (); /* Handle failure */ if (!pixmap || gdk_error_trap_pop ()) { memset (pixmap, 0, sizeof (*pixmap)); return FALSE; } gdk_error_trap_push (); if (d->frame_window) buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb); else buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba); gdk_flush (); /* Handle failure */ if (!buffer_pixmap || gdk_error_trap_pop ()) { memset (buffer_pixmap, 0, sizeof (*buffer_pixmap)); g_object_unref (G_OBJECT (pixmap)); return FALSE; } /* Create XRender context */ format = get_format_for_drawable (d, GDK_DRAWABLE (buffer_pixmap)); picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap), format, 0, NULL); /* Destroy the old pixmaps and pictures */ if (d->pixmap) g_object_unref (d->pixmap); if (d->x11Pixmap) decor_post_delete_pixmap (xdisplay, wnck_window_get_xid (d->win), d->x11Pixmap); if (d->buffer_pixmap) g_object_unref (G_OBJECT (d->buffer_pixmap)); if (d->picture) XRenderFreePicture (xdisplay, d->picture); if (d->cr) cairo_destroy (d->cr); /* Assign new pixmaps and pictures */ d->pixmap = pixmap; d->x11Pixmap = GDK_PIXMAP_XID (d->pixmap); d->buffer_pixmap = buffer_pixmap; d->cr = gdk_cairo_create (pixmap); d->picture = picture; d->prop_xid = wnck_window_get_xid (win); update_window_decoration_name (win); /* Redraw decoration on idle */ queue_decor_draw (d); return TRUE; }
int my_wnck_error_trap_pop (void) { XSync (gdk_x11_get_default_xdisplay (), False); return gdk_error_trap_pop (); }
/* * update_event_windows * * Returns: void * Description: creates small "event windows" for the buttons specified to be * on the titlebar by wnck. Note here that for the pixmap mode we create actual * X windows but in the reparenting mode this is not possible so we create event * capture boxes on the window instead. The geometry of the decoration is retrieved * with window_get_client_window_geometry and adjusted for shade. Also we * need to query the theme for what window positions are appropriate here. * * This function works on the buttons and also the small event regions that we need * in order to toggle certain actions on the window decoration (eg resize, move) * * So your window decoration might look something like this (not to scale): * * ----------------------------------------------------------- * | rtl | rt | rtr | * | --- |---------------------------------------------| --- | * | | [i][s][m] mv [_][M][X] | | * | |---------------------------------------------| | * | | | | * | rl | window contents | rr | * | | | | * | | | | * | --- |---------------------------------------------| --- | * | rbl | rb | rbr | * ----------------------------------------------------------- * * Where: * - rtl = resize top left * - rtr = resize top right * - rbl = resize bottom left * - rbr = resize bottom right * - rt = resize top * - rb = resize bottom * - rl = resize left * - rr = resize right * - mv = "grab move" area (eg titlebar) * - i = icon * - s = shade * - m = menu * - _ = minimize * - M = maximize * - X = close * * For the reparenting mode we use button_windows[i].pos and for the pixmap mode * we use buttons_windows[i].window * */ void update_event_windows (WnckWindow *win) { Display *xdisplay; decor_t *d = g_object_get_data (G_OBJECT (win), "decor"); gint x0, y0, width, height, x, y, w, h; gint i, j, k, l; gint actions = d->actions; xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); /* Get the geometry of the client */ wnck_window_get_client_window_geometry (win, &x0, &y0, &width, &height); /* Shaded windows have no height - also skip some event windows */ if (d->state & WNCK_WINDOW_STATE_SHADED) { height = 0; k = l = 1; } else { k = 0; l = 2; } gdk_error_trap_push (); /* [rtl, ru, rtr], [rl, mv, rr], [rbl, rb, rbr] */ for (i = 0; i < 3; ++i) { static guint event_window_actions[3][3] = { { WNCK_WINDOW_ACTION_RESIZE, WNCK_WINDOW_ACTION_RESIZE, WNCK_WINDOW_ACTION_RESIZE }, { WNCK_WINDOW_ACTION_RESIZE, WNCK_WINDOW_ACTION_MOVE, WNCK_WINDOW_ACTION_RESIZE }, { WNCK_WINDOW_ACTION_RESIZE, WNCK_WINDOW_ACTION_RESIZE, WNCK_WINDOW_ACTION_RESIZE } }; for (j = 0; j < 3; ++j) { w = 0; h = 0; if (actions & event_window_actions[i][j] && i >= k && i <= l) (*theme_get_event_window_position) (d, i, j, width, height, &x, &y, &w, &h); /* Reparenting mode - create boxes which we monitor motionnotify on */ if (d->frame_window) { BoxPtr box = &d->event_windows[i][j].pos; box->x1 = x; box->x2 = x + w; box->y1 = y; box->y2 = y + h; } /* Pixmap mode with window geometry - create small event windows */ else if (!d->frame_window && w != 0 && h != 0) { XMapWindow (xdisplay, d->event_windows[i][j].window); XMoveResizeWindow (xdisplay, d->event_windows[i][j].window, x, y, w, h); } /* No parent and no geometry - unmap all event windows */ else if (!d->frame_window) { XUnmapWindow (xdisplay, d->event_windows[i][j].window); } } } /* no button event windows if width is less than minimum width */ if (width < ICON_SPACE + d->button_width) actions = 0; /* Above, stick, unshade and unstick are only available in wnck => 2.18.1 */ for (i = 0; i < BUTTON_NUM; ++i) { static guint button_actions[BUTTON_NUM] = { WNCK_WINDOW_ACTION_CLOSE, WNCK_WINDOW_ACTION_MAXIMIZE, WNCK_WINDOW_ACTION_MINIMIZE, 0, WNCK_WINDOW_ACTION_SHADE, #ifdef HAVE_LIBWNCK_2_18_1 WNCK_WINDOW_ACTION_ABOVE, WNCK_WINDOW_ACTION_STICK, WNCK_WINDOW_ACTION_UNSHADE, WNCK_WINDOW_ACTION_ABOVE, WNCK_WINDOW_ACTION_UNSTICK #else 0, 0, 0, 0, 0 #endif }; /* Reparenting mode - if a box was set and we no longer need it reset its geometry */ if (d->frame_window && button_actions[i] && !(actions & button_actions[i])) { memset (&d->button_windows[i].pos, 0, sizeof (Box)); } /* Pixmap mode - if a box was set and we no longer need it unmap its window */ else if (!d->frame_window && button_actions[i] && !(actions & button_actions[i])) { XUnmapWindow (xdisplay, d->button_windows[i].window); continue; } /* Reparenting mode - if there is a button position for this * button then set the geometry */ if (d->frame_window && (*theme_get_button_position) (d, i, width, height, &x, &y, &w, &h)) { BoxPtr box = &d->button_windows[i].pos; box->x1 = x; box->y1 = y; box->x2 = x + w; box->y2 = y + h; } /* Pixmap mode - if there is a button position for this button then map the window * and resize it to this position */ else if (!d->frame_window && (*theme_get_button_position) (d, i, width, height, &x, &y, &w, &h)) { Window win = d->button_windows[i].window; XMapWindow (xdisplay, win); XMoveResizeWindow (xdisplay, win, x, y, w, h); } else if (!d->frame_window) { XUnmapWindow (xdisplay, d->button_windows[i].window); } } gdk_display_sync (gdk_display_get_default ()); gdk_error_trap_pop (); }
void nsScreenGtk :: Init (GdkWindow *aRootWindow) { gint scale = nsScreenGtk::GetGtkMonitorScaleFactor(); gint width = gdk_screen_width()*scale; gint height = gdk_screen_height()*scale; // We listen for configure events on the root window to pick up // changes to this rect. We could listen for "size_changed" signals // on the default screen to do this, except that doesn't work with // versions of GDK predating the GdkScreen object. See bug 256646. mAvailRect = mRect = nsIntRect(0, 0, width, height); #ifdef MOZ_X11 // We need to account for the taskbar, etc in the available rect. // See http://freedesktop.org/Standards/wm-spec/index.html#id2767771 // XXX do we care about _NET_WM_STRUT_PARTIAL? That will // add much more complexity to the code here (our screen // could have a non-rectangular shape), but should // lead to greater accuracy. long *workareas; GdkAtom type_returned; int format_returned; int length_returned; GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL); gdk_error_trap_push(); // gdk_property_get uses (length + 3) / 4, hence G_MAXLONG - 3 here. if (!gdk_property_get(aRootWindow, gdk_atom_intern ("_NET_WORKAREA", FALSE), cardinal_atom, 0, G_MAXLONG - 3, FALSE, &type_returned, &format_returned, &length_returned, (guchar **) &workareas)) { // This window manager doesn't support the freedesktop standard. // Nothing we can do about it, so assume full screen size. return; } // Flush the X queue to catch errors now. gdk_flush(); if (!gdk_error_trap_pop() && type_returned == cardinal_atom && length_returned && (length_returned % 4) == 0 && format_returned == 32) { int num_items = length_returned / sizeof(long); for (int i = 0; i < num_items; i += 4) { nsIntRect workarea(workareas[i], workareas[i + 1], workareas[i + 2], workareas[i + 3]); if (!mRect.Contains(workarea)) { // Note that we hit this when processing screen size changes, // since we'll get the configure event before the toolbars have // been moved. We'll end up cleaning this up when we get the // change notification to the _NET_WORKAREA property. However, // we still want to listen to both, so we'll handle changes // properly for desktop environments that don't set the // _NET_WORKAREA property. NS_WARNING("Invalid bounds"); continue; } mAvailRect.IntersectRect(mAvailRect, workarea); } } g_free (workareas); #endif }
guint egg_tray_icon_send_message (EggTrayIcon *icon, gint timeout, const gchar *message, gint len) { guint stamp; g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0); g_return_val_if_fail (timeout >= 0, 0); g_return_val_if_fail (message != NULL, 0); #ifdef GDK_WINDOWING_X11 if (icon->manager_window == None) return 0; #endif if (len < 0) len = strlen (message); stamp = icon->stamp++; #ifdef GDK_WINDOWING_X11 /* Get ready to send the message */ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, icon->manager_window, timeout, len, stamp); /* Now to send the actual message */ gdk_error_trap_push (); while (len > 0) { XClientMessageEvent ev; Display *xdisplay; xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); ev.type = ClientMessage; ev.window = icon->manager_window; ev.format = 8; ev.message_type = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_MESSAGE_DATA", False); if (len > 20) { memcpy (&ev.data, message, 20); len -= 20; message += 20; } else { memcpy (&ev.data, message, len); len = 0; } XSendEvent (xdisplay, icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev); XSync (xdisplay, False); } gdk_error_trap_pop (); #endif return stamp; }
static void activate_window(Display *display, Window window) { Window toplevel = window; Atom window_state_atom = gdk_x11_get_xatom_by_name("WM_STATE"); Atom active_window_atom = gdk_x11_get_xatom_by_name("_NET_ACTIVE_WINDOW"); Window root; XEvent xev; /* The window_id we have is the window ID of a child window. So, we first * need to walk up the window hierarachy until we find the WM_STATE window, * then activate that window. Lots of X roundtrips here, but we only do * this on a user click as an alternative to launching a new firefox * process, so it doesn't really matter. */ gdk_error_trap_push(); while (TRUE) { Window parent; Window *children; guint n_children; Atom type; int format; gulong n_items; gulong bytes_after; guchar *data; if (!XQueryTree(display, toplevel, &root, &parent, &children, &n_children)) { g_debug("XQueryTree failed\n"); goto out; } XFree(children); if (root == parent) /* No window manager or non-reparenting window manager */ break; if (XGetWindowProperty(display, toplevel, window_state_atom, 0, G_MAXLONG, False, AnyPropertyType, &type, &format, &n_items, &bytes_after, &data) != Success) { g_debug("XGetWindowProperty failed\n"); goto out; } if (type != None) { /* Found the real client toplevel */ XFree(data); break; } toplevel = parent; } xev.xclient.type = ClientMessage; xev.xclient.window = toplevel; xev.xclient.message_type = active_window_atom; xev.xclient.format = 32; xev.xclient.data.l[0] = 2; /* We're sort of like a pager ... we're activating a window * from a different app as a response to direct user action */ xev.xclient.data.l[1] = gtk_get_current_event_time(); xev.xclient.data.l[2] = None; /* We don't really have an active toplevel */ xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; XSendEvent(display, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev); out: gdk_error_trap_pop(); }
/* Doesn't handle HIPPO_WINDOW_STATE_ACTIVE - see comment below */ static HippoWindowState get_window_state(Display *display, Window window) { HippoWindowState result = HIPPO_WINDOW_STATE_HIDDEN; XWindowAttributes window_attributes; GdkRectangle rect; GdkRegion *visible_region = NULL; Window child = None; Window root; Window parent; Window *children = NULL; guint n_children; gdk_error_trap_push(); /* First check if the window and all ancestors are mapped */ if (!XGetWindowAttributes(display, window, &window_attributes)) { g_debug("XGetWindowAttributes failed\n"); goto out; } if (window_attributes.map_state != IsViewable) goto out; /* Get the area of the window in parent coordinates */ rect.x = window_attributes.x; rect.y = window_attributes.y; rect.width = window_attributes.width; rect.height = window_attributes.height; visible_region = gdk_region_rectangle(&rect); if (!XQueryTree(display, window, &root, &parent, &children, &n_children)) { g_debug("XQueryTree failed\n"); goto out; } XFree(children); children = NULL; child = window; window = parent; /* Walk up the hierarchy, clipping to parents, and subtracting * overlayed siblings (yuck!) */ while (TRUE) { GdkRegion *parent_region; gboolean seen_child = FALSE; int x, y; unsigned int width, height, border, depth; unsigned int i; gdk_region_get_clipbox(visible_region, &rect); /* Clip to parent */ if (!XGetGeometry(display, window, &root, &x, &y, &width, &height, &border, &depth)) { g_debug("XGetGeometry failed\n"); goto out; } rect.x = 0; rect.y = 0; rect.width = width; rect.height= height; parent_region = gdk_region_rectangle(&rect); gdk_region_intersect(visible_region, parent_region); gdk_region_destroy(parent_region); if (gdk_region_empty(visible_region)) goto out; if (!XQueryTree(display, window, &root, &parent, &children, &n_children)) { g_debug("XQueryTree failed\n"); goto out; } for (i = 0; i < n_children; i++) { if (seen_child) { /* A sibling above */ GdkRegion *child_region; XWindowAttributes child_attributes; if (!XGetWindowAttributes(display, children[i], &child_attributes)) { g_debug("XGetWindowAttributes failed for child\n"); goto out; } if (child_attributes.map_state == IsViewable) { rect.x = child_attributes.x - child_attributes.border_width; rect.y = child_attributes.y - child_attributes.border_width; rect.width = child_attributes.width + 2 * child_attributes.border_width; rect.height = child_attributes.height + 2 * child_attributes.border_width; child_region = gdk_region_rectangle(&rect); gdk_region_subtract(visible_region, child_region); gdk_region_destroy(child_region); if (gdk_region_empty(visible_region)) goto out; } } else if (children[i] == child) { seen_child = TRUE; } } XFree(children); children = NULL; if (window == root) break; child = window; window = parent; /* Translate to parent coordinates */ gdk_region_offset(visible_region, x, y); } if (!gdk_region_empty(visible_region)) result = HIPPO_WINDOW_STATE_ONSCREEN; out: gdk_error_trap_pop(); if (children) XFree(children); if (visible_region) gdk_region_destroy(visible_region); return result; }