void meta_window_destroy_frame (MetaWindow *window) { MetaFrame *frame; if (window->frame == NULL) return; meta_verbose ("Unframing window %s\n", window->desc); frame = window->frame; meta_bell_notify_frame_destroy (frame); /* Unparent the client window; it may be destroyed, * thus the error trap. */ meta_error_trap_push (window->display); if (window->mapped) { window->mapped = FALSE; /* Keep track of unmapping it, so we * can identify a withdraw initiated * by the client. */ meta_topic (META_DEBUG_WINDOW_STATE, "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc); window->unmaps_pending += 1; } XReparentWindow (window->display->xdisplay, window->xwindow, window->screen->xroot, /* Using anything other than meta_window_get_position() * coordinates here means we'll need to ensure a configure * notify event is sent; see bug 399552. */ window->frame->rect.x, window->frame->rect.y); meta_error_trap_pop (window->display, FALSE); meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow); meta_display_unregister_x_window (window->display, frame->xwindow); window->frame = NULL; /* Move keybindings to window instead of frame */ meta_window_grab_keys (window); g_free (frame); /* Put our state back where it should be */ meta_window_queue (window, META_QUEUE_CALC_SHOWING); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); }
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace) { GList *tmp; GList *windows; int i; if (workspace->work_areas_invalid) { meta_topic (META_DEBUG_WORKAREA, "Work area for workspace %d is already invalid\n", meta_workspace_index (workspace)); return; } meta_topic (META_DEBUG_WORKAREA, "Invalidating work area for workspace %d\n", meta_workspace_index (workspace)); /* If we are in the middle of a resize or move operation, we * might have cached pointers to the workspace's edges */ if (workspace == workspace->screen->active_workspace) meta_display_cleanup_edges (workspace->screen->display); g_free (workspace->work_area_monitor); workspace->work_area_monitor = NULL; workspace_free_struts (workspace); for (i = 0; i < workspace->screen->n_monitor_infos; i++) g_list_free_full (workspace->monitor_region[i], g_free); g_free (workspace->monitor_region); g_list_free_full (workspace->screen_region, g_free); g_list_free_full (workspace->screen_edges, g_free); g_list_free_full (workspace->monitor_edges, g_free); workspace->monitor_region = NULL; workspace->screen_region = NULL; workspace->screen_edges = NULL; workspace->monitor_edges = NULL; workspace->work_areas_invalid = TRUE; /* redo the size/position constraints on all windows */ windows = meta_workspace_list_windows (workspace); tmp = windows; while (tmp != NULL) { MetaWindow *w = tmp->data; meta_window_queue (w, META_QUEUE_MOVE_RESIZE); tmp = tmp->next; } g_list_free (windows); meta_screen_queue_workarea_recalc (workspace->screen); }
void meta_core_queue_frame_resize (Display *xdisplay, Window frame_xwindow) { MetaWindow *window = get_window (xdisplay, frame_xwindow); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); }
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace) { GList *tmp; GList *windows; int i; if (workspace->work_areas_invalid) { meta_topic (META_DEBUG_WORKAREA, "Work area for workspace %d is already invalid\n", meta_workspace_index (workspace)); return; } meta_topic (META_DEBUG_WORKAREA, "Invalidating work area for workspace %d\n", meta_workspace_index (workspace)); g_free (workspace->work_area_xinerama); workspace->work_area_xinerama = NULL; workspace_free_struts (workspace); for (i = 0; i < workspace->screen->n_xinerama_infos; i++) meta_rectangle_free_list_and_elements (workspace->xinerama_region[i]); g_free (workspace->xinerama_region); meta_rectangle_free_list_and_elements (workspace->screen_region); meta_rectangle_free_list_and_elements (workspace->screen_edges); meta_rectangle_free_list_and_elements (workspace->xinerama_edges); workspace->xinerama_region = NULL; workspace->screen_region = NULL; workspace->screen_edges = NULL; workspace->xinerama_edges = NULL; workspace->work_areas_invalid = TRUE; /* redo the size/position constraints on all windows */ windows = meta_workspace_list_windows (workspace); tmp = windows; while (tmp != NULL) { MetaWindow *w = tmp->data; meta_window_queue (w, META_QUEUE_MOVE_RESIZE); tmp = tmp->next; } g_list_free (windows); meta_screen_queue_workarea_recalc (workspace->screen); }
void meta_workspace_add_window (MetaWorkspace *workspace, MetaWindow *window) { g_return_if_fail (window->workspace == NULL); /* If the window is on all workspaces, we want to add it to all mru * lists, otherwise just add it to this workspaces mru list */ if (window->on_all_workspaces) { if (window->workspace == NULL) { GList* tmp = window->screen->workspaces; while (tmp) { MetaWorkspace* work = (MetaWorkspace*) tmp->data; if (!g_list_find (work->mru_list, window)) work->mru_list = g_list_prepend (work->mru_list, window); tmp = tmp->next; } } } else { g_assert (g_list_find (workspace->mru_list, window) == NULL); workspace->mru_list = g_list_prepend (workspace->mru_list, window); } workspace->windows = g_list_prepend (workspace->windows, window); window->workspace = workspace; meta_window_set_current_workspace_hint (window); if (window->struts) { meta_topic (META_DEBUG_WORKAREA, "Invalidating work area of workspace %d since we're adding window %s to it\n", meta_workspace_index (workspace), window->desc); meta_workspace_invalidate_work_area (workspace); } /* queue a move_resize since changing workspaces may change * the relevant struts */ meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE); g_signal_emit (workspace, signals[WINDOW_ADDED], 0, window); g_object_notify (G_OBJECT (workspace), "n-windows"); }
void meta_workspace_queue_calc_showing (MetaWorkspace *workspace) { GList *tmp; tmp = workspace->windows; while (tmp != NULL) { meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING); tmp = tmp->next; } }
void meta_workspace_remove_window (MetaWorkspace *workspace, MetaWindow *window) { g_return_if_fail (window->workspace == workspace); workspace->windows = g_list_remove (workspace->windows, window); window->workspace = NULL; /* If the window is on all workspaces, we don't want to remove it * from the MRU list unless this causes it to be removed from all * workspaces */ if (window->on_all_workspaces) { GList* tmp = window->screen->workspaces; while (tmp) { MetaWorkspace* work = (MetaWorkspace*) tmp->data; work->mru_list = g_list_remove (work->mru_list, window); tmp = tmp->next; } } else { workspace->mru_list = g_list_remove (workspace->mru_list, window); g_assert (g_list_find (workspace->mru_list, window) == NULL); } meta_window_set_current_workspace_hint (window); if (window->struts) { meta_topic (META_DEBUG_WORKAREA, "Invalidating work area of workspace %d since we're removing window %s from it\n", meta_workspace_index (workspace), window->desc); meta_workspace_invalidate_work_area (workspace); } /* queue a move_resize since changing workspaces may change * the relevant struts */ meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE); g_signal_emit (workspace, signals[WINDOW_REMOVED], 0, window); g_object_notify (G_OBJECT (workspace), "n-windows"); }
void meta_window_destroy_frame (MetaWindow *window) { MetaFrame *frame; MetaFrameBorders borders; if (window->frame == NULL) return; meta_verbose ("Unframing window %s\n", window->desc); frame = window->frame; meta_frame_calc_borders (frame, &borders); meta_bell_notify_frame_destroy (frame); /* Unparent the client window; it may be destroyed, * thus the error trap. */ meta_error_trap_push (window->display); if (window->mapped) { window->mapped = FALSE; /* Keep track of unmapping it, so we * can identify a withdraw initiated * by the client. */ meta_topic (META_DEBUG_WINDOW_STATE, "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc); window->unmaps_pending += 1; } meta_stack_tracker_record_add (window->screen->stack_tracker, window->xwindow, XNextRequest (window->display->xdisplay)); XReparentWindow (window->display->xdisplay, window->xwindow, window->screen->xroot, /* Using anything other than client root window coordinates * coordinates here means we'll need to ensure a configure * notify event is sent; see bug 399552. */ window->frame->rect.x + borders.invisible.left, window->frame->rect.y + borders.invisible.top); meta_error_trap_pop (window->display); meta_ui_frame_unmanage (frame->ui_frame); meta_display_unregister_x_window (window->display, frame->xwindow); window->frame = NULL; if (window->frame_bounds) { cairo_region_destroy (window->frame_bounds); window->frame_bounds = NULL; } /* Move keybindings to window instead of frame */ meta_window_grab_keys (window); g_free (frame); /* Put our state back where it should be */ meta_window_queue (window, META_QUEUE_CALC_SHOWING); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); }