00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <config.h>
00027 #include "frame-private.h"
00028 #include "bell.h"
00029 #include "errors.h"
00030 #include "keybindings.h"
00031
00032 #ifdef HAVE_RENDER
00033 #include <X11/extensions/Xrender.h>
00034 #endif
00035
00036 #define EVENT_MASK (SubstructureRedirectMask | \
00037 StructureNotifyMask | SubstructureNotifyMask | \
00038 ExposureMask | \
00039 ButtonPressMask | ButtonReleaseMask | \
00040 PointerMotionMask | PointerMotionHintMask | \
00041 EnterWindowMask | LeaveWindowMask | \
00042 FocusChangeMask | \
00043 ColormapChangeMask)
00044
00045 void
00046 meta_window_ensure_frame (MetaWindow *window)
00047 {
00048 MetaFrame *frame;
00049 XSetWindowAttributes attrs;
00050 Visual *visual;
00051
00052 if (window->frame)
00053 return;
00054
00055
00056 meta_display_grab (window->display);
00057
00058 frame = g_new (MetaFrame, 1);
00059
00060 frame->window = window;
00061 frame->xwindow = None;
00062
00063 frame->rect = window->rect;
00064 frame->child_x = 0;
00065 frame->child_y = 0;
00066 frame->bottom_height = 0;
00067 frame->right_width = 0;
00068 frame->current_cursor = 0;
00069
00070 frame->mapped = FALSE;
00071 frame->need_reapply_frame_shape = TRUE;
00072 frame->is_flashing = FALSE;
00073
00074 meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
00075 window->desc,
00076 XVisualIDFromVisual (window->xvisual) ==
00077 XVisualIDFromVisual (window->screen->default_xvisual) ?
00078 "is" : "is not",
00079 window->depth, window->screen->default_depth);
00080 meta_verbose ("Frame geometry %d,%d %dx%d\n",
00081 frame->rect.x, frame->rect.y,
00082 frame->rect.width, frame->rect.height);
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 if (window->depth == 32)
00097 visual = window->xvisual;
00098 else
00099 visual = NULL;
00100
00101 frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
00102 window->display->xdisplay,
00103 visual,
00104 frame->rect.x,
00105 frame->rect.y,
00106 frame->rect.width,
00107 frame->rect.height,
00108 frame->window->screen->number);
00109
00110 meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
00111 attrs.event_mask = EVENT_MASK;
00112 XChangeWindowAttributes (window->display->xdisplay,
00113 frame->xwindow, CWEventMask, &attrs);
00114
00115 meta_display_register_x_window (window->display, &frame->xwindow, window);
00116
00117
00118
00119
00120 meta_ui_reset_frame_bg (window->screen->ui, frame->xwindow);
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 meta_error_trap_push (window->display);
00131 if (window->mapped)
00132 {
00133 window->mapped = FALSE;
00134
00135
00136 meta_topic (META_DEBUG_WINDOW_STATE,
00137 "Incrementing unmaps_pending on %s for reparent\n", window->desc);
00138 window->unmaps_pending += 1;
00139 }
00140
00141 window->rect.x = 0;
00142 window->rect.y = 0;
00143
00144 XReparentWindow (window->display->xdisplay,
00145 window->xwindow,
00146 frame->xwindow,
00147 window->rect.x,
00148 window->rect.y);
00149
00150 meta_error_trap_pop (window->display, FALSE);
00151
00152
00153 window->frame = frame;
00154
00155 if (window->title)
00156 meta_ui_set_frame_title (window->screen->ui,
00157 window->frame->xwindow,
00158 window->title);
00159
00160
00161 meta_window_grab_keys (window);
00162
00163
00164 meta_ui_apply_frame_shape (frame->window->screen->ui,
00165 frame->xwindow,
00166 frame->rect.width,
00167 frame->rect.height,
00168 frame->window->has_shape);
00169 frame->need_reapply_frame_shape = FALSE;
00170
00171 meta_display_ungrab (window->display);
00172 }
00173
00174 void
00175 meta_window_destroy_frame (MetaWindow *window)
00176 {
00177 MetaFrame *frame;
00178
00179 if (window->frame == NULL)
00180 return;
00181
00182 meta_verbose ("Unframing window %s\n", window->desc);
00183
00184 frame = window->frame;
00185
00186 meta_bell_notify_frame_destroy (frame);
00187
00188
00189
00190
00191 meta_error_trap_push (window->display);
00192 if (window->mapped)
00193 {
00194 window->mapped = FALSE;
00195
00196
00197
00198 meta_topic (META_DEBUG_WINDOW_STATE,
00199 "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc);
00200 window->unmaps_pending += 1;
00201 }
00202 XReparentWindow (window->display->xdisplay,
00203 window->xwindow,
00204 window->screen->xroot,
00205
00206
00207
00208
00209 window->frame->rect.x,
00210 window->frame->rect.y);
00211 meta_error_trap_pop (window->display, FALSE);
00212
00213 meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow);
00214
00215 meta_display_unregister_x_window (window->display,
00216 frame->xwindow);
00217
00218 window->frame = NULL;
00219
00220
00221 meta_window_grab_keys (window);
00222
00223 g_free (frame);
00224
00225
00226 meta_window_queue (window, META_QUEUE_CALC_SHOWING);
00227 }
00228
00229
00230 MetaFrameFlags
00231 meta_frame_get_flags (MetaFrame *frame)
00232 {
00233 MetaFrameFlags flags;
00234
00235 flags = 0;
00236
00237 if (frame->window->border_only)
00238 {
00239 ;
00240
00241
00242 }
00243 else
00244 {
00245 flags |= META_FRAME_ALLOWS_MENU;
00246
00247 if (frame->window->has_close_func)
00248 flags |= META_FRAME_ALLOWS_DELETE;
00249
00250 if (frame->window->has_maximize_func)
00251 flags |= META_FRAME_ALLOWS_MAXIMIZE;
00252
00253 if (frame->window->has_minimize_func)
00254 flags |= META_FRAME_ALLOWS_MINIMIZE;
00255
00256 if (frame->window->has_shade_func)
00257 flags |= META_FRAME_ALLOWS_SHADE;
00258 }
00259
00260 if (META_WINDOW_ALLOWS_MOVE (frame->window))
00261 flags |= META_FRAME_ALLOWS_MOVE;
00262
00263 if (META_WINDOW_ALLOWS_HORIZONTAL_RESIZE (frame->window))
00264 flags |= META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
00265
00266 if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
00267 flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
00268
00269 if (frame->window->has_focus)
00270 flags |= META_FRAME_HAS_FOCUS;
00271
00272 if (frame->window->shaded)
00273 flags |= META_FRAME_SHADED;
00274
00275 if (frame->window->on_all_workspaces)
00276 flags |= META_FRAME_STUCK;
00277
00278
00279
00280
00281 if (META_WINDOW_MAXIMIZED (frame->window))
00282 flags |= META_FRAME_MAXIMIZED;
00283
00284 if (frame->window->fullscreen)
00285 flags |= META_FRAME_FULLSCREEN;
00286
00287 if (frame->is_flashing)
00288 flags |= META_FRAME_IS_FLASHING;
00289
00290 if (frame->window->wm_state_above)
00291 flags |= META_FRAME_ABOVE;
00292
00293 return flags;
00294 }
00295
00296 void
00297 meta_frame_calc_geometry (MetaFrame *frame,
00298 MetaFrameGeometry *geomp)
00299 {
00300 MetaFrameGeometry geom;
00301 MetaWindow *window;
00302
00303 window = frame->window;
00304
00305 meta_ui_get_frame_geometry (window->screen->ui,
00306 frame->xwindow,
00307 &geom.top_height,
00308 &geom.bottom_height,
00309 &geom.left_width,
00310 &geom.right_width);
00311
00312 *geomp = geom;
00313 }
00314
00315 static void
00316 update_shape (MetaFrame *frame)
00317 {
00318 if (frame->need_reapply_frame_shape)
00319 {
00320 meta_ui_apply_frame_shape (frame->window->screen->ui,
00321 frame->xwindow,
00322 frame->rect.width,
00323 frame->rect.height,
00324 frame->window->has_shape);
00325 frame->need_reapply_frame_shape = FALSE;
00326 }
00327 }
00328
00329 void
00330 meta_frame_sync_to_window (MetaFrame *frame,
00331 int resize_gravity,
00332 gboolean need_move,
00333 gboolean need_resize)
00334 {
00335 if (!(need_move || need_resize))
00336 {
00337 update_shape (frame);
00338 return;
00339 }
00340
00341 meta_topic (META_DEBUG_GEOMETRY,
00342 "Syncing frame geometry %d,%d %dx%d (SE: %d,%d)\n",
00343 frame->rect.x, frame->rect.y,
00344 frame->rect.width, frame->rect.height,
00345 frame->rect.x + frame->rect.width,
00346 frame->rect.y + frame->rect.height);
00347
00348
00349 if (need_resize)
00350 {
00351 meta_ui_unflicker_frame_bg (frame->window->screen->ui,
00352 frame->xwindow,
00353 frame->rect.width,
00354 frame->rect.height);
00355
00356
00357 frame->need_reapply_frame_shape = TRUE;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366 update_shape (frame);
00367
00368 meta_ui_move_resize_frame (frame->window->screen->ui,
00369 frame->xwindow,
00370 frame->rect.x,
00371 frame->rect.y,
00372 frame->rect.width,
00373 frame->rect.height);
00374
00375 if (need_resize)
00376 {
00377 meta_ui_reset_frame_bg (frame->window->screen->ui,
00378 frame->xwindow);
00379
00380
00381
00382
00383 if (frame->window->display->grab_window ==
00384 frame->window)
00385 meta_ui_repaint_frame (frame->window->screen->ui,
00386 frame->xwindow);
00387 }
00388 }
00389
00390 void
00391 meta_frame_queue_draw (MetaFrame *frame)
00392 {
00393 meta_ui_queue_frame_draw (frame->window->screen->ui,
00394 frame->xwindow);
00395 }
00396
00397 void
00398 meta_frame_set_screen_cursor (MetaFrame *frame,
00399 MetaCursor cursor)
00400 {
00401 Cursor xcursor;
00402 if (cursor == frame->current_cursor)
00403 return;
00404 frame->current_cursor = cursor;
00405 if (cursor == META_CURSOR_DEFAULT)
00406 XUndefineCursor (frame->window->display->xdisplay, frame->xwindow);
00407 else
00408 {
00409 xcursor = meta_display_create_x_cursor (frame->window->display, cursor);
00410 XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor);
00411 XFlush (frame->window->display->xdisplay);
00412 XFreeCursor (frame->window->display->xdisplay, xcursor);
00413 }
00414 }
00415
00416 Window
00417 meta_frame_get_xwindow (MetaFrame *frame)
00418 {
00419 return frame->xwindow;
00420 }