void meta_compositor_remove_window (MetaCompositor *compositor, MetaWindow *window) { MetaWindowActor *window_actor = NULL; MetaScreen *screen; MetaCompScreen *info; DEBUG_TRACE ("meta_compositor_remove_window\n"); window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); if (!window_actor) return; screen = meta_window_get_screen (window); info = meta_screen_get_compositor_data (screen); if (window_actor == info->unredirected_window) { meta_window_actor_set_redirected (window_actor, TRUE); meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), NULL); info->unredirected_window = NULL; } meta_window_actor_destroy (window_actor); }
static void add_win (MetaWindow *window) { MetaScreen *screen = meta_window_get_screen (window); MetaCompScreen *info = meta_screen_get_compositor_data (screen); g_return_if_fail (info != NULL); meta_window_actor_new (window); sync_actor_stacking (info); }
static void pre_paint_windows (MetaCompScreen *info) { GList *l; MetaWindowActor *top_window; MetaWindowActor *expected_unredirected_window = NULL; if (info->windows == NULL) return; top_window = g_list_last (info->windows)->data; if (meta_window_actor_should_unredirect (top_window) && info->disable_unredirect_count == 0) expected_unredirected_window = top_window; if (info->unredirected_window != expected_unredirected_window) { if (info->unredirected_window != NULL) { meta_window_actor_set_redirected (info->unredirected_window, TRUE); meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), NULL); } if (expected_unredirected_window != NULL) { meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)), meta_window_actor_get_meta_window (top_window)); meta_window_actor_set_redirected (top_window, FALSE); } info->unredirected_window = expected_unredirected_window; } for (l = info->windows; l; l = l->next) meta_window_actor_pre_paint (l->data); }
void meta_compositor_add_window (MetaCompositor *compositor, MetaWindow *window) { MetaScreen *screen = meta_window_get_screen (window); MetaDisplay *display = meta_screen_get_display (screen); DEBUG_TRACE ("meta_compositor_add_window\n"); meta_error_trap_push (display); add_win (window); meta_error_trap_pop (display); }
void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); MetaScreen *screen = meta_window_get_screen (window); MetaCompScreen *info = meta_screen_get_compositor_data (screen); DEBUG_TRACE ("meta_compositor_sync_window_geometry\n"); g_return_if_fail (info); if (!window_actor) return; meta_window_actor_sync_actor_position (window_actor); }
void meta_window_ensure_frame (MetaWindow *window) { MetaFrame *frame; MetaScreen *screen; XSetWindowAttributes attrs; XVisualInfo visual_info; Visual *visual; int status; if (window->frame) return; /* See comment below for why this is required. */ meta_display_grab (window->display); frame = g_new (MetaFrame, 1); frame->window = window; frame->xwindow = None; frame->rect = window->rect; frame->child_x = 0; frame->child_y = 0; frame->bottom_height = 0; frame->right_width = 0; frame->current_cursor = 0; frame->mapped = TRUE; frame->need_reapply_frame_shape = TRUE; frame->is_flashing = FALSE; meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n", window->desc, XVisualIDFromVisual (window->xvisual) == XVisualIDFromVisual (window->screen->default_xvisual) ? "is" : "is not", window->depth, window->screen->default_depth); meta_verbose ("Frame geometry %d,%d %dx%d\n", frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height); /* Default depth/visual handles clients with weird visuals; they can * always be children of the root depth/visual obviously, but * e.g. DRI games can't be children of a parent that has the same * visual as the client. NULL means default visual. * * We look for an ARGB visual if we can find one, otherwise use * the default of NULL. */ screen = meta_window_get_screen (window); status = XMatchVisualInfo (window->display->xdisplay, XScreenNumberOfScreen (screen->xscreen), 32, TrueColor, &visual_info); if (!status) { /* Special case for depth 32 windows (assumed to be ARGB), * we use the window's visual. Otherwise we just use the system visual. */ if (window->depth == 32) visual = window->xvisual; else visual = NULL; } else visual = visual_info.visual; frame->xwindow = meta_ui_create_frame_window (window->screen->ui, window->display->xdisplay, visual, frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height, frame->window->screen->number); meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow); attrs.event_mask = EVENT_MASK; XChangeWindowAttributes (window->display->xdisplay, frame->xwindow, CWEventMask, &attrs); meta_display_register_x_window (window->display, &frame->xwindow, window); /* Reparent the client window; it may be destroyed, * thus the error trap. We'll get a destroy notify later * and free everything. Comment in FVWM source code says * we need a server grab or the child can get its MapNotify * before we've finished reparenting and getting the decoration * window onscreen, so ensure_frame must be called with * a grab. */ meta_error_trap_push (window->display); if (window->mapped) { window->mapped = FALSE; /* the reparent will unmap the window, * we don't want to take that as a withdraw */ meta_topic (META_DEBUG_WINDOW_STATE, "Incrementing unmaps_pending on %s for reparent\n", window->desc); window->unmaps_pending += 1; } /* window was reparented to this position */ window->rect.x = 0; window->rect.y = 0; XReparentWindow (window->display->xdisplay, window->xwindow, frame->xwindow, window->rect.x, window->rect.y); /* FIXME handle this error */ meta_error_trap_pop (window->display, FALSE); /* stick frame to the window */ window->frame = frame; meta_ui_map_frame (window->screen->ui, window->frame->xwindow); /* Now that frame->xwindow is registered with window, we can set its * style and background. */ meta_ui_update_frame_style (window->screen->ui, frame->xwindow); if (window->title) meta_ui_set_frame_title (window->screen->ui, window->frame->xwindow, window->title); /* Move keybindings to frame instead of window */ meta_window_grab_keys (window); /* Shape mask */ meta_ui_apply_frame_shape (frame->window->screen->ui, frame->xwindow, frame->rect.width, frame->rect.height, frame->window->has_shape); frame->need_reapply_frame_shape = FALSE; meta_display_ungrab (window->display); { Display* xdisplay = window->display->xdisplay; unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Motion); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISelectEvents (xdisplay, frame->xwindow, &mask, 1); } meta_prefs_add_listener (prefs_changed_callback, frame); }
/** * meta_compositor_process_event: (skip) * */ gboolean meta_compositor_process_event (MetaCompositor *compositor, XEvent *event, MetaWindow *window) { if (compositor->modal_plugin && is_grabbed_event (event)) { MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin); if (klass->xevent_filter) klass->xevent_filter (compositor->modal_plugin, event); /* We always consume events even if the plugin says it didn't handle them; * exclusive is exclusive */ return TRUE; } if (window) { MetaCompScreen *info; MetaScreen *screen; screen = meta_window_get_screen (window); info = meta_screen_get_compositor_data (screen); if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) { DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n"); return TRUE; } } else { GSList *l; l = meta_display_get_screens (compositor->display); while (l) { MetaScreen *screen = l->data; MetaCompScreen *info; info = meta_screen_get_compositor_data (screen); if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) { DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n"); return TRUE; } l = l->next; } } switch (event->type) { case PropertyNotify: process_property_notify (compositor, (XPropertyEvent *) event, window); break; default: if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) { /* Core code doesn't handle damage events, so we need to extract the MetaWindow * ourselves */ if (window == NULL) { Window xwin = ((XDamageNotifyEvent *) event)->drawable; window = meta_display_lookup_x_window (compositor->display, xwin); } DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); process_damage (compositor, (XDamageNotifyEvent *) event, window); } break; } /* Clutter needs to know about MapNotify events otherwise it will think the stage is invisible */ if (event->type == MapNotify) clutter_x11_handle_event (event); /* The above handling is basically just "observing" the events, so we return * FALSE to indicate that the event should not be filtered out; if we have * GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example. */ return FALSE; }