Adds support in src/core for tracking override redirect windows.

The metacity core is now directly aware of override redirect windows.
- They get MetaWindows like normal windows, so mutter no longer need to special
  case them. The net wm types applicable to override redirects are also
  recognised.
- The original positioning/stacking semantics of metacity with respect to OR
  windows are maintained, but now it's easier to synchronize the stacking
  between the core and mutter.
- mutter no longer needs to manualy track UnmapNotify, MapNotify,
  ReparentNotify, CreateNotify and DestroyNotify events; instead map, unmap,
  add and remove events can now be consistently delivered via the
  MetaCompositor callbacks.
This commit is contained in:
Robert Bragg 2008-11-23 19:28:40 +00:00
parent 13badba158
commit 6849735e9d
17 changed files with 796 additions and 839 deletions

View File

@ -33,11 +33,9 @@ struct _MetaCompositor
void (*unmanage_screen) (MetaCompositor *compositor,
MetaScreen *screen);
void (*add_window) (MetaCompositor *compositor,
MetaWindow *window,
Window xwindow,
XWindowAttributes *attrs);
MetaWindow *window);
void (*remove_window) (MetaCompositor *compositor,
Window xwindow);
MetaWindow *window);
void (*set_updates) (MetaCompositor *compositor,
MetaWindow *window,
gboolean update);
@ -49,40 +47,34 @@ struct _MetaCompositor
void (*set_active_window) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window);
/* local additions */
void (*destroy_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*map_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*unmap_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*minimize_window) (MetaCompositor *compositor,
MetaWindow *window);
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void (*unminimize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void (*maximize_window) (MetaCompositor *compositor,
MetaWindow *window,
int x,
int y,
int width,
int height);
MetaRectangle *window_rect);
void (*unmaximize_window) (MetaCompositor *compositor,
MetaWindow *window,
int x,
int y,
int width,
int height);
MetaRectangle *window_rect);
void (*update_workspace_geometry) (MetaCompositor *compositor,
MetaWorkspace *workspace);
void (*switch_workspace) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWorkspace *from,
MetaWorkspace *to,
MetaMotionDirection direction);
void (*sync_stack) (MetaCompositor *compositor,
MetaScreen *screen,
GList *stack);
void (*set_window_hidden) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,

View File

@ -911,7 +911,7 @@ window_has_shadow (MetaCompWindow *cw)
}
if (cw->type == META_COMP_WINDOW_MENU ||
cw->type == META_COMP_WINDOW_DROP_DOWN_MENU) {
cw->type == META_COMP_WINDOW_DROPDOWN_MENU) {
meta_verbose ("Window has shadow as it is a menu\n");
return TRUE;
}
@ -1776,7 +1776,7 @@ get_window_type (MetaDisplay *display,
else if (type_atom == compositor->atom_net_wm_window_type_menu)
cw->type = META_COMP_WINDOW_MENU;
else if (type_atom == compositor->atom_net_wm_window_type_dropdown_menu)
cw->type = META_COMP_WINDOW_DROP_DOWN_MENU;
cw->type = META_COMP_WINDOW_DROPDOWN_MENU;
else if (type_atom == compositor->atom_net_wm_window_type_tooltip)
cw->type = META_COMP_WINDOW_TOOLTIP;
else

View File

@ -57,23 +57,21 @@ meta_compositor_destroy (MetaCompositor *compositor)
void
meta_compositor_add_window (MetaCompositor *compositor,
MetaWindow *window,
Window xwindow,
XWindowAttributes *attrs)
MetaWindow *window)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->add_window)
compositor->add_window (compositor, window, xwindow, attrs);
compositor->add_window (compositor, window);
#endif
}
void
meta_compositor_remove_window (MetaCompositor *compositor,
Window xwindow)
MetaWindow *window)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->remove_window)
compositor->remove_window (compositor, xwindow);
compositor->remove_window (compositor, window);
#endif
}
@ -165,57 +163,69 @@ void meta_compositor_end_move (MetaCompositor *compositor,
{
}
void meta_compositor_free_window (MetaCompositor *compositor,
MetaWindow *window)
void
meta_compositor_map_window (MetaCompositor *compositor,
MetaWindow *window)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->map_window)
compositor->map_window (compositor, window);
#endif
}
void
meta_compositor_destroy_window (MetaCompositor *compositor,
MetaWindow *window)
meta_compositor_unmap_window (MetaCompositor *compositor,
MetaWindow *window)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->destroy_window)
compositor->destroy_window (compositor, window);
if (compositor && compositor->unmap_window)
compositor->unmap_window (compositor, window);
#endif
}
void
meta_compositor_minimize_window (MetaCompositor *compositor,
MetaWindow *window)
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->minimize_window)
compositor->minimize_window (compositor, window);
compositor->minimize_window (compositor, window, window_rect, icon_rect);
#endif
}
void
meta_compositor_unminimize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->unminimize_window)
compositor->unminimize_window (compositor, window, window_rect, icon_rect);
#endif
}
void
meta_compositor_maximize_window (MetaCompositor *compositor,
MetaWindow *window,
int x,
int y,
int width,
int height)
MetaRectangle *window_rect)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->maximize_window)
compositor->maximize_window (compositor, window, x, y, width, height);
compositor->maximize_window (compositor, window, window_rect);
#endif
}
void
meta_compositor_unmaximize_window (MetaCompositor *compositor,
MetaWindow *window,
int x,
int y,
int width,
int height)
MetaRectangle *window_rect)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
if (compositor && compositor->unmaximize_window)
compositor->unmaximize_window (compositor, window, x, y, width, height);
compositor->unmaximize_window (compositor, window, window_rect);
#endif
}

File diff suppressed because it is too large Load Diff

View File

@ -145,6 +145,13 @@ meta_core_get (Display *xdisplay,
case META_WINDOW_DOCK:
case META_WINDOW_TOOLBAR:
case META_WINDOW_SPLASHSCREEN:
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
case META_WINDOW_OVERRIDE_OTHER:
/* No frame */
base_type = META_FRAME_TYPE_LAST;
break;

View File

@ -2020,7 +2020,8 @@ event_callback (XEvent *event,
"Window %s withdrawn\n",
window->desc);
meta_effect_run_close (window, NULL, NULL);
if (!window->override_redirect)
meta_effect_run_close (window, NULL, NULL);
/* Unmanage withdrawn window */
window->withdrawn = TRUE;
@ -2045,6 +2046,15 @@ event_callback (XEvent *event,
}
break;
case MapNotify:
/* NB: override redirect windows wont cause a map request so we
* watch out for map notifies against any root windows too if a
* compositor is enabled: */
if (display->compositor && window == NULL
&& meta_display_screen_for_root (display, event->xmap.event))
{
window = meta_window_new (display, event->xmap.window,
FALSE);
}
break;
case MapRequest:
if (window == NULL)
@ -2073,29 +2083,32 @@ event_callback (XEvent *event,
case ReparentNotify:
break;
case ConfigureNotify:
/* Handle screen resize */
{
MetaScreen *screen;
if (window && window->override_redirect)
meta_window_configure_notify (window, &event->xconfigure);
else
/* Handle screen resize */
{
MetaScreen *screen;
screen = meta_display_screen_for_root (display,
event->xconfigure.window);
screen = meta_display_screen_for_root (display,
event->xconfigure.window);
if (screen != NULL)
{
if (screen != NULL)
{
#ifdef HAVE_RANDR
/* do the resize the official way */
XRRUpdateConfiguration (event);
/* do the resize the official way */
XRRUpdateConfiguration (event);
#else
/* poke around in Xlib */
screen->xscreen->width = event->xconfigure.width;
screen->xscreen->height = event->xconfigure.height;
/* poke around in Xlib */
screen->xscreen->width = event->xconfigure.width;
screen->xscreen->height = event->xconfigure.height;
#endif
meta_screen_resize (screen,
event->xconfigure.width,
event->xconfigure.height);
}
}
meta_screen_resize (screen,
event->xconfigure.width,
event->xconfigure.height);
}
}
break;
case ConfigureRequest:
/* This comment and code is found in both twm and fvwm */

View File

@ -862,7 +862,8 @@ meta_window_grab_keys (MetaWindow *window)
if (window->all_keys_grabbed)
return;
if (window->type == META_WINDOW_DOCK)
if (window->type == META_WINDOW_DOCK
|| window->override_redirect)
{
if (window->keys_grabbed)
ungrab_all_keys (window->display, window->xwindow);

View File

@ -394,6 +394,14 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
case META_WINDOW_DESKTOP:
case META_WINDOW_DIALOG:
case META_WINDOW_MODAL_DIALOG:
/* override redirect window types: */
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
case META_WINDOW_OVERRIDE_OTHER:
break;
case META_WINDOW_NORMAL:
@ -680,6 +688,14 @@ meta_window_place (MetaWindow *window,
case META_WINDOW_TOOLBAR:
case META_WINDOW_MENU:
case META_WINDOW_UTILITY:
/* override redirect window types: */
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
case META_WINDOW_OVERRIDE_OTHER:
goto done_no_constraints;
}
@ -713,6 +729,14 @@ meta_window_place (MetaWindow *window,
case META_WINDOW_TOOLBAR:
case META_WINDOW_MENU:
case META_WINDOW_UTILITY:
/* override redirect window types: */
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
case META_WINDOW_OVERRIDE_OTHER:
if (window->size_hints.flags & PPosition)
{
meta_topic (META_DEBUG_PLACEMENT,

View File

@ -790,20 +790,6 @@ meta_screen_manage_all_windows (MetaScreen *screen)
window = meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
&info->attrs);
if (info->xwindow == screen->no_focus_window ||
info->xwindow == screen->flash_window ||
#ifdef HAVE_COMPOSITE_EXTENSIONS
info->xwindow == screen->wm_cm_selection_window ||
info->xwindow == screen->guard_window ||
#endif
info->xwindow == screen->wm_sn_selection_window) {
meta_verbose ("Not managing our own windows\n");
continue;
}
if (screen->display->compositor)
meta_compositor_add_window (screen->display->compositor, window,
info->xwindow, &info->attrs);
}
meta_stack_thaw (screen->stack);
@ -818,38 +804,20 @@ meta_screen_composite_all_windows (MetaScreen *screen)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
MetaDisplay *display;
GList *windows, *list;
GSList *windows, *tmp;
display = screen->display;
if (!display->compositor)
return;
windows = list_windows (screen);
windows = meta_display_list_windows (display);
for (tmp = windows; tmp != NULL; tmp = tmp->next)
meta_compositor_add_window (display->compositor, tmp->data);
g_slist_free (windows);
/* trigger a stack_sync_to_server: */
meta_stack_freeze (screen->stack);
for (list = windows; list != NULL; list = list->next)
{
WindowInfo *info = list->data;
if (info->xwindow == screen->no_focus_window ||
info->xwindow == screen->flash_window ||
info->xwindow == screen->wm_sn_selection_window ||
info->xwindow == screen->wm_cm_selection_window) {
meta_verbose ("Not managing our own windows\n");
continue;
}
meta_compositor_add_window (display->compositor,
meta_display_lookup_x_window (display,
info->xwindow),
info->xwindow, &info->attrs);
}
meta_stack_thaw (screen->stack);
g_list_foreach (windows, (GFunc)g_free, NULL);
g_list_free (windows);
#endif
}

View File

@ -698,6 +698,20 @@ window_type_to_string (MetaWindowType type)
return "splashscreen";
case META_WINDOW_UTILITY:
return "utility";
case META_WINDOW_DROPDOWN_MENU:
return "dropdown_menu";
case META_WINDOW_POPUP_MENU:
return "popup_menu";
case META_WINDOW_TOOLTIP:
return "tooltip";
case META_WINDOW_NOTIFICATION:
return "notification";
case META_WINDOW_COMBO:
return "combo";
case META_WINDOW_DND:
return "dnd";
case META_WINDOW_OVERRIDE_OTHER:
return "override_redirect";
}
return "";

View File

@ -265,6 +265,14 @@ get_standalone_layer (MetaWindow *window)
layer = META_LAYER_DOCK;
break;
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_OVERRIDE_OTHER:
layer = META_LAYER_OVERRIDE_REDIRECT;
break;
default:
meta_window_foreach_transient (window,
is_focused_foreach,
@ -1062,6 +1070,7 @@ stack_sync_to_server (MetaStack *stack)
GArray *root_children_stacked;
GList *tmp;
GArray *all_hidden;
int n_override_redirect = 0;
/* Bail out if frozen */
if (stack->freeze_count > 0)
@ -1100,7 +1109,10 @@ stack_sync_to_server (MetaStack *stack)
w->layer, w->stack_position, w->desc);
/* remember, stacked is in reverse order (bottom to top) */
g_array_prepend_val (stacked, w->xwindow);
if (w->override_redirect)
n_override_redirect++;
else
g_array_prepend_val (stacked, w->xwindow);
if (w->frame)
top_level_window = w->frame->xwindow;
@ -1124,7 +1136,7 @@ stack_sync_to_server (MetaStack *stack)
meta_pop_no_msg_prefix ();
/* All windows should be in some stacking order */
if (stacked->len != stack->windows->len)
if (stacked->len != stack->windows->len - n_override_redirect)
meta_bug ("%u windows stacked, %u windows exist in stack\n",
stacked->len, stack->windows->len);

View File

@ -49,14 +49,15 @@
*/
typedef enum
{
META_LAYER_DESKTOP = 0,
META_LAYER_BOTTOM = 1,
META_LAYER_NORMAL = 2,
META_LAYER_TOP = 4, /* Same as DOCK; see EWMH and bug 330717 */
META_LAYER_DOCK = 4,
META_LAYER_FULLSCREEN = 5,
META_LAYER_FOCUSED_WINDOW = 6,
META_LAYER_LAST = 7
META_LAYER_DESKTOP = 0,
META_LAYER_BOTTOM = 1,
META_LAYER_NORMAL = 2,
META_LAYER_TOP = 4, /* Same as DOCK; see EWMH and bug 330717 */
META_LAYER_DOCK = 4,
META_LAYER_FULLSCREEN = 5,
META_LAYER_FOCUSED_WINDOW = 6,
META_LAYER_OVERRIDE_REDIRECT = 7,
META_LAYER_LAST = 8
} MetaStackLayer;
/**

View File

@ -110,6 +110,9 @@ struct _MetaWindow
/* Initial timestamp property */
guint32 initial_timestamp;
/* Whether this is an override redirect window or not */
guint override_redirect : 1;
/* Whether we're maximized */
guint maximized_horizontally : 1;
guint maximized_vertically : 1;

View File

@ -53,6 +53,10 @@
#include <X11/extensions/shape.h>
#endif
#ifdef HAVE_COMPOSITE_EXTENSIONS
#include <X11/extensions/Xcomposite.h>
#endif
static int destroying_windows_disallowed = 0;
@ -253,6 +257,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
Atom initial_props[N_INITIAL_PROPS];
int i;
gboolean has_shape;
MetaScreen *screen;
g_assert (attrs != NULL);
g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
@ -266,12 +271,43 @@ meta_window_new_with_attrs (MetaDisplay *display,
return NULL;
}
if (attrs->override_redirect)
screen = NULL;
for (tmp = display->screens; tmp != NULL; tmp = tmp->next)
{
meta_verbose ("Deciding not to manage override_redirect window 0x%lx\n", xwindow);
return NULL;
MetaScreen *scr = tmp->data;
if (scr->xroot == attrs->root)
{
screen = tmp->data;
break;
}
}
g_assert (screen);
/* A black list of override redirect windows that we don't need to manage: */
if (attrs->override_redirect &&
(xwindow == screen->no_focus_window ||
xwindow == screen->flash_window ||
xwindow == screen->wm_sn_selection_window ||
attrs->class == InputOnly ||
/* any windows created via meta_create_offscreen_window: */
(attrs->x == -100 && attrs->y == -100
&& attrs->width == 1 && attrs->height == 1) ||
#ifdef HAVE_COMPOSITE_EXTENSIONS
xwindow == screen->wm_cm_selection_window ||
xwindow == screen->guard_window ||
(display->compositor &&
xwindow == XCompositeGetOverlayWindow (display->xdisplay,
screen->xroot)
)
#endif
)
) {
meta_verbose ("Not managing our own windows\n");
return NULL;
}
/* Grab server */
meta_display_grab (display);
meta_error_trap_push (display); /* Push a trap over all of window
@ -330,6 +366,8 @@ meta_window_new_with_attrs (MetaDisplay *display,
event_mask =
PropertyChangeMask | EnterWindowMask | LeaveWindowMask |
FocusChangeMask | ColormapChangeMask;
if (attrs->override_redirect)
event_mask |= StructureNotifyMask;
XSelectInput (display->xdisplay, xwindow, event_mask);
@ -384,8 +422,6 @@ meta_window_new_with_attrs (MetaDisplay *display,
return NULL;
}
g_assert (!attrs->override_redirect);
window = g_new (MetaWindow, 1);
window->constructing = TRUE;
@ -408,25 +444,12 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->sync_request_time.tv_usec = 0;
#endif
window->screen = NULL;
tmp = display->screens;
while (tmp != NULL)
{
MetaScreen *scr = tmp->data;
if (scr->xroot == attrs->root)
{
window->screen = tmp->data;
break;
}
tmp = tmp->next;
}
g_assert (window->screen);
window->screen = screen;
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
window->override_redirect = attrs->override_redirect;
/* avoid tons of stack updates */
meta_stack_freeze (window->screen->stack);
@ -608,10 +631,12 @@ meta_window_new_with_attrs (MetaDisplay *display,
meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
update_sm_hints (window); /* must come after transient_for */
if (!window->override_redirect)
update_sm_hints (window); /* must come after transient_for */
update_role (window);
update_net_wm_type (window);
meta_window_update_icon_now (window);
if (!window->override_redirect)
meta_window_update_icon_now (window);
if (window->initially_iconic)
{
@ -672,14 +697,15 @@ meta_window_new_with_attrs (MetaDisplay *display,
meta_window_ensure_frame (window);
meta_window_grab_keys (window);
if (window->type != META_WINDOW_DOCK)
if (window->type != META_WINDOW_DOCK && !window->override_redirect)
{
meta_display_grab_window_buttons (window->display, window->xwindow);
meta_display_grab_focus_window_button (window->display, window);
}
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK)
window->type == META_WINDOW_DOCK ||
window->override_redirect)
{
/* Change the default, but don't enforce this if the user
* focuses the dock/desktop and unsticks it using key shortcuts.
@ -759,7 +785,8 @@ meta_window_new_with_attrs (MetaDisplay *display,
}
/* for the various on_all_workspaces = TRUE possible above */
meta_window_set_current_workspace_hint (window);
if (!window->override_redirect)
meta_window_set_current_workspace_hint (window);
meta_window_update_struts (window);
@ -800,11 +827,14 @@ meta_window_new_with_attrs (MetaDisplay *display,
}
}
/* FIXME we have a tendency to set this then immediately
* change it again.
*/
set_wm_state (window, window->iconic ? IconicState : NormalState);
set_net_wm_state (window);
if (!window->override_redirect)
{
/* FIXME we have a tendency to set this then immediately
* change it again.
*/
set_wm_state (window, window->iconic ? IconicState : NormalState);
set_net_wm_state (window);
}
/* Sync stack changes */
meta_stack_thaw (window->screen->stack);
@ -837,6 +867,9 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->constructing = FALSE;
if (screen->display->compositor)
meta_compositor_add_window (screen->display->compositor, window);
return window;
}
@ -988,7 +1021,7 @@ meta_window_free (MetaWindow *window,
meta_verbose ("Unmanaging 0x%lx\n", window->xwindow);
if (window->display->compositor)
meta_compositor_destroy_window (window->display->compositor, window);
meta_compositor_remove_window (window->display->compositor, window);
if (window->display->window_with_menu == window)
{
@ -1495,7 +1528,9 @@ implement_showing (MetaWindow *window,
if (window->display->compositor)
{
meta_compositor_minimize_window (window->display->compositor,
window);
window,
&window_rect,
&icon_rect);
finish_minimize (window);
}
else
@ -2001,6 +2036,14 @@ window_state_on_map (MetaWindow *window,
case META_WINDOW_DESKTOP:
case META_WINDOW_SPLASHSCREEN:
case META_WINDOW_MENU:
/* override redirect types: */
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
case META_WINDOW_OVERRIDE_OTHER:
/* don't focus any of these; places_on_top may be irrelevant for some of
* these (e.g. dock)--but you never know--the focus window might also be
* of the same type in some weird situation...
@ -2274,22 +2317,33 @@ meta_window_show (MetaWindow *window)
}
}
if (did_show && window->was_minimized)
if (did_show)
{
MetaRectangle window_rect;
MetaRectangle icon_rect;
window->was_minimized = FALSE;
if (meta_window_get_icon_geometry (window, &icon_rect))
if (window->was_minimized
&& meta_window_get_icon_geometry (window, &icon_rect))
{
MetaRectangle window_rect;
meta_window_get_outer_rect (window, &window_rect);
meta_effect_run_unminimize (window,
&window_rect,
&icon_rect,
NULL, NULL);
if (window->display->compositor)
meta_compositor_unminimize_window (window->display->compositor,
window,
&window_rect,
&icon_rect);
else
meta_effect_run_unminimize (window,
&window_rect,
&icon_rect,
NULL, NULL);
}
else
meta_compositor_map_window (window->display->compositor,
window);
window->was_minimized = FALSE;
}
if (window->iconic)
@ -2373,10 +2427,16 @@ meta_window_hide (MetaWindow *window)
window->hidden);
meta_stack_thaw (window->screen->stack);
meta_compositor_unmap_window (window->display->compositor,
window);
did_hide = TRUE;
}
else
{
meta_compositor_unmap_window (window->display->compositor,
window);
if (window->frame && window->frame->mapped)
{
meta_topic (META_DEBUG_WINDOW_STATE, "Frame actually needs unmap\n");
@ -2650,14 +2710,14 @@ meta_window_maximize (MetaWindow *window,
if (window->display->compositor)
{
MetaRectangle window_rect;
meta_window_move_resize_now (window);
meta_window_get_outer_rect (window, &window_rect);
meta_compositor_maximize_window (window->display->compositor,
window,
window->frame->rect.x,
window->frame->rect.y,
window->frame->rect.width,
window->frame->rect.height);
&window_rect);
}
else
{
@ -2763,6 +2823,8 @@ meta_window_unmaximize (MetaWindow *window,
if (window->display->compositor)
{
MetaRectangle window_rect;
meta_window_move_resize (window,
FALSE,
target_rect.x,
@ -2771,12 +2833,11 @@ meta_window_unmaximize (MetaWindow *window,
target_rect.height);
meta_window_move_resize_now (window);
meta_window_get_outer_rect (window, &window_rect);
meta_compositor_unmaximize_window (window->display->compositor,
window,
window->frame->rect.x,
window->frame->rect.y,
window->frame->rect.width,
window->frame->rect.height);
window,
&window_rect);
}
else
{
@ -3803,6 +3864,22 @@ idle_move_resize (gpointer data)
return FALSE;
}
/* This is used to notify us of an unrequested configuration
* (only applicable to override redirect windows) */
void
meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event)
{
g_assert (window->override_redirect);
g_assert (window->frame == NULL);
window->rect.x = event->x;
window->rect.y = event->y;
window->rect.width = event->width;
window->rect.height = event->height;
if (!event->override_redirect && !event->send_event)
meta_warning ("Unhandled change of windows override redirect status\n");
}
void
meta_window_get_position (MetaWindow *window,
int *x,
@ -5847,10 +5924,18 @@ update_net_wm_type (MetaWindow *window)
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH)
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
atoms[i] ==
window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP ||
atoms[i] ==
window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND ||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
{
window->type_atom = atoms[i];
break;
@ -6177,7 +6262,24 @@ recalc_window_type (MetaWindow *window)
old_type = window->type;
if (window->type_atom != None)
if (window->override_redirect)
{
if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
window->type = META_WINDOW_DROPDOWN_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU)
window->type = META_WINDOW_POPUP_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP)
window->type = META_WINDOW_TOOLTIP;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION)
window->type = META_WINDOW_NOTIFICATION;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO)
window->type = META_WINDOW_COMBO;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND)
window->type = META_WINDOW_DND;
else
window->type = META_WINDOW_OVERRIDE_OTHER;
}
else if (window->type_atom != None)
{
if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP)
window->type = META_WINDOW_DESKTOP;
@ -6187,14 +6289,14 @@ recalc_window_type (MetaWindow *window)
window->type = META_WINDOW_TOOLBAR;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU)
window->type = META_WINDOW_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG)
window->type = META_WINDOW_DIALOG;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
window->type = META_WINDOW_NORMAL;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY)
window->type = META_WINDOW_UTILITY;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH)
window->type = META_WINDOW_SPLASHSCREEN;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG)
window->type = META_WINDOW_DIALOG;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
window->type = META_WINDOW_NORMAL;
else
meta_bug ("Set a type atom for %s that wasn't handled in recalc_window_type\n",
window->desc);
@ -6219,7 +6321,8 @@ recalc_window_type (MetaWindow *window)
{
recalc_window_features (window);
set_net_wm_state (window);
if (!window->override_redirect)
set_net_wm_state (window);
/* Update frame */
if (window->decorated)
@ -6370,12 +6473,14 @@ recalc_window_features (MetaWindow *window)
window->decorated = FALSE;
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK)
window->type == META_WINDOW_DOCK ||
window->override_redirect)
window->always_sticky = TRUE;
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK ||
window->type == META_WINDOW_SPLASHSCREEN)
window->type == META_WINDOW_SPLASHSCREEN ||
window->override_redirect)
{
window->decorated = FALSE;
window->has_close_func = FALSE;
@ -6463,6 +6568,13 @@ recalc_window_features (MetaWindow *window)
case META_WINDOW_MENU:
case META_WINDOW_UTILITY:
case META_WINDOW_SPLASHSCREEN:
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
case META_WINDOW_OVERRIDE_OTHER:
window->skip_taskbar = TRUE;
window->skip_pager = TRUE;
break;
@ -8340,3 +8452,20 @@ meta_window_get_description (MetaWindow *window)
return window->desc;
}
void *
meta_window_get_compositor_private (MetaWindow *window)
{
if (!window)
return NULL;
return window->compositor_private;
}
void
meta_window_set_compositor_private (MetaWindow *window, void *priv)
{
if (!window)
return;
window->compositor_private = priv;
}

View File

@ -106,7 +106,15 @@ item(_NET_WM_WINDOW_TYPE_DESKTOP)
item(_NET_WM_WINDOW_TYPE_DOCK)
item(_NET_WM_WINDOW_TYPE_TOOLBAR)
item(_NET_WM_WINDOW_TYPE_MENU)
item(_NET_WM_WINDOW_TYPE_UTILITY)
item(_NET_WM_WINDOW_TYPE_SPLASH)
item(_NET_WM_WINDOW_TYPE_DIALOG)
item(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
item(_NET_WM_WINDOW_TYPE_POPUP_MENU)
item(_NET_WM_WINDOW_TYPE_TOOLTIP)
item(_NET_WM_WINDOW_TYPE_NOTIFICATION)
item(_NET_WM_WINDOW_TYPE_COMBO)
item(_NET_WM_WINDOW_TYPE_DND)
item(_NET_WM_WINDOW_TYPE_NORMAL)
item(_NET_WM_STATE_MODAL)
item(_NET_CLIENT_LIST)
@ -120,9 +128,6 @@ item(_NET_WM_MOVERESIZE)
item(_NET_ACTIVE_WINDOW)
item(_NET_WM_STRUT)
item(_NET_WM_STATE_HIDDEN)
item(_NET_WM_WINDOW_TYPE_UTILITY)
item(_NET_WM_WINDOW_TYPE_SPLASH)
item(_NET_WM_WINDOW_TYPE_DND)
item(_NET_WM_STATE_FULLSCREEN)
item(_NET_WM_PING)
item(_NET_WM_PID)

View File

@ -32,24 +32,27 @@
typedef enum _MetaCompWindowType
{
/*
* Types shared with MetaWindow
*/
META_COMP_WINDOW_NORMAL = META_WINDOW_NORMAL,
META_COMP_WINDOW_DESKTOP = META_WINDOW_DESKTOP,
META_COMP_WINDOW_DOCK = META_WINDOW_DOCK,
META_COMP_WINDOW_MENU = META_WINDOW_MENU,
META_COMP_WINDOW_NORMAL = META_WINDOW_NORMAL,
META_COMP_WINDOW_DESKTOP = META_WINDOW_DESKTOP,
META_COMP_WINDOW_DOCK = META_WINDOW_DOCK,
META_COMP_WINDOW_DIALOG = META_WINDOW_DIALOG,
META_COMP_WINDOW_MODAL_DIALOG = META_WINDOW_MODAL_DIALOG,
META_COMP_WINDOW_TOOLBAR = META_WINDOW_TOOLBAR,
META_COMP_WINDOW_MENU = META_WINDOW_MENU,
META_COMP_WINDOW_UTILITY = META_WINDOW_UTILITY,
META_COMP_WINDOW_SPLASHSCREEN = META_WINDOW_SPLASHSCREEN,
/* override redirect window types, */
META_COMP_WINDOW_DROPDOWN_MENU = META_WINDOW_DROPDOWN_MENU,
META_COMP_WINDOW_POPUP_MENU = META_WINDOW_POPUP_MENU,
META_COMP_WINDOW_TOOLTIP = META_WINDOW_TOOLTIP,
META_COMP_WINDOW_NOTIFICATION = META_WINDOW_NOTIFICATION,
META_COMP_WINDOW_COMBO = META_WINDOW_COMBO,
META_COMP_WINDOW_DND = META_WINDOW_DND,
META_COMP_WINDOW_OVERRIDE_OTHER = META_WINDOW_OVERRIDE_OTHER
/*
* Extended types that WM does not care about, but we do.
*/
META_COMP_WINDOW_TOOLTIP = 0xf000,
META_COMP_WINDOW_DROP_DOWN_MENU,
META_COMP_WINDOW_DND,
META_COMP_WINDOW_OVERRIDE,
} MetaCompWindowType;
#ifdef WITH_CLUTTER
extern int meta_compositor_can_use_clutter__;
#endif
@ -62,11 +65,9 @@ void meta_compositor_unmanage_screen (MetaCompositor *compositor,
MetaScreen *screen);
void meta_compositor_add_window (MetaCompositor *compositor,
MetaWindow *window,
Window xwindow,
XWindowAttributes *attrs);
MetaWindow *window);
void meta_compositor_remove_window (MetaCompositor *compositor,
Window xwindow);
MetaWindow *window);
void meta_compositor_set_updates (MetaCompositor *compositor,
MetaWindow *window,
@ -94,28 +95,34 @@ void meta_compositor_free_window (MetaCompositor *compositor,
MetaWindow *window);
void
meta_compositor_destroy_window (MetaCompositor *compositor,
MetaWindow *window);
meta_compositor_map_window (MetaCompositor *compositor,
MetaWindow *window);
void
meta_compositor_unmap_window (MetaCompositor *compositor,
MetaWindow *window);
void
meta_compositor_minimize_window (MetaCompositor *compositor,
MetaWindow *window);
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void
meta_compositor_unminimize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void
meta_compositor_maximize_window (MetaCompositor *compositor,
MetaWindow *window,
int x,
int y,
int width,
int height);
MetaRectangle *window_rect);
void
meta_compositor_unmaximize_window (MetaCompositor *compositor,
MetaWindow *window,
int x,
int y,
int width,
int height);
MetaRectangle *window_rect);
void
meta_compositor_update_workspace_geometry (MetaCompositor *compositor,
@ -138,7 +145,6 @@ meta_compositor_set_window_hidden (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
gboolean hidden);
#endif

View File

@ -39,6 +39,15 @@ typedef enum
META_WINDOW_MENU,
META_WINDOW_UTILITY,
META_WINDOW_SPLASHSCREEN,
/* override redirect window types: */
META_WINDOW_DROPDOWN_MENU,
META_WINDOW_POPUP_MENU,
META_WINDOW_TOOLTIP,
META_WINDOW_NOTIFICATION,
META_WINDOW_COMBO,
META_WINDOW_DND,
META_WINDOW_OVERRIDE_OTHER
} MetaWindowType;
typedef enum
@ -72,4 +81,7 @@ void meta_window_change_workspace_by_index (MetaWindow *window,
gint space_index,
gboolean append,
guint32 timestamp);
void *meta_window_get_compositor_private (MetaWindow *window);
void meta_window_set_compositor_private (MetaWindow *window, void *priv);
void meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event);
#endif