From 6f7023bc6b2a65c30fb4ca5b664ce73f0e2aab9d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 11:20:22 -0400 Subject: [PATCH] Start splitting the X11-specific stuff of MetaWindow out into a subclass This is fairly simple and basic for now, with just skip_taskbar / skip_pager, but eventually a lot of "WM policy" like this, including move-resize, will be in subclasses for each individual surface. --- src/Makefile.am | 1 + src/core/window-private.h | 8 +++--- src/core/window-props.c | 12 ++++++--- src/core/window-x11-private.h | 48 +++++++++++++++++++++++++++++++++++ src/core/window-x11.c | 40 +++++++++++++++++++++++++++-- src/core/window-x11.h | 14 ++++++++++ src/core/window.c | 34 +++++++++++++++++++++---- 7 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 src/core/window-x11-private.h diff --git a/src/Makefile.am b/src/Makefile.am index 8df85fbd7..25044e382 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -165,6 +165,7 @@ libmutter_wayland_la_SOURCES = \ core/window-props.h \ core/window-x11.c \ core/window-x11.h \ + core/window-x11-private.h \ core/window.c \ core/window-private.h \ meta/window.h \ diff --git a/src/core/window-private.h b/src/core/window-private.h index e8eecd991..4ef970779 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -266,10 +266,6 @@ struct _MetaWindow /* Weird "_NET_WM_STATE_MODAL" flag */ guint wm_state_modal : 1; - /* TRUE if the client forced these on */ - guint wm_state_skip_taskbar : 1; - guint wm_state_skip_pager : 1; - /* Computed whether to skip taskbar or not */ guint skip_taskbar : 1; guint skip_pager : 1; @@ -465,6 +461,10 @@ struct _MetaWindow struct _MetaWindowClass { GObjectClass parent_class; + + void (*get_default_skip_hints) (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out); }; /* These differ from window->has_foo_func in that they consider diff --git a/src/core/window-props.c b/src/core/window-props.c index dc6f9ba70..35f056920 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -40,6 +40,7 @@ #include #include "window-props.h" #include "window-x11.h" +#include "window-x11-private.h" #include #include "xprops.h" #include "frame.h" @@ -666,6 +667,9 @@ reload_net_wm_state (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + int i; /* We know this is only an initial window creation, @@ -684,8 +688,8 @@ reload_net_wm_state (MetaWindow *window, window->maximized_vertically = FALSE; window->fullscreen = FALSE; window->wm_state_modal = FALSE; - window->wm_state_skip_taskbar = FALSE; - window->wm_state_skip_pager = FALSE; + priv->wm_state_skip_taskbar = FALSE; + priv->wm_state_skip_pager = FALSE; window->wm_state_above = FALSE; window->wm_state_below = FALSE; window->wm_state_demands_attention = FALSE; @@ -707,9 +711,9 @@ reload_net_wm_state (MetaWindow *window, else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MODAL) window->wm_state_modal = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_TASKBAR) - window->wm_state_skip_taskbar = TRUE; + priv->wm_state_skip_taskbar = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER) - window->wm_state_skip_pager = TRUE; + priv->wm_state_skip_pager = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN) window->fullscreen_after_placement = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE) diff --git a/src/core/window-x11-private.h b/src/core/window-x11-private.h new file mode 100644 index 000000000..25114daad --- /dev/null +++ b/src/core/window-x11-private.h @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington, Anders Carlsson + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "window-private.h" + +#ifndef META_WINDOW_X11_PRIVATE_H +#define META_WINDOW_X11_PRIVATE_H + +G_BEGIN_DECLS + +typedef struct _MetaWindowX11Private MetaWindowX11Private; + +struct _MetaWindowX11 +{ + MetaWindow parent; + + MetaWindowX11Private *priv; +}; + +struct _MetaWindowX11Private +{ + /* TRUE if the client forced these on */ + guint wm_state_skip_taskbar : 1; + guint wm_state_skip_pager : 1; +}; + +G_END_DECLS + +#endif diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 5787cb685..cade6561c 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -23,6 +23,7 @@ #include "config.h" #include "window-x11.h" +#include "window-x11-private.h" #include #include @@ -44,6 +45,39 @@ #include "window-props.h" #include "xprops.h" +struct _MetaWindowX11Class +{ + MetaWindowClass parent_class; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW) + +static void +meta_window_x11_init (MetaWindowX11 *window_x11) +{ + window_x11->priv = meta_window_x11_get_instance_private (window_x11); +} + +static void +meta_window_x11_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + *skip_taskbar_out = priv->wm_state_skip_taskbar; + *skip_pager_out = priv->wm_state_skip_pager; +} + +static void +meta_window_x11_class_init (MetaWindowX11Class *klass) +{ + MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + + window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; +} + void meta_window_x11_set_net_wm_state (MetaWindow *window) { @@ -694,6 +728,8 @@ gboolean meta_window_x11_client_message (MetaWindow *window, XEvent *event) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); MetaDisplay *display; display = window->display; @@ -879,7 +915,7 @@ meta_window_x11_client_message (MetaWindow *window, if (first == display->atom__NET_WM_STATE_SKIP_PAGER || second == display->atom__NET_WM_STATE_SKIP_PAGER) { - window->wm_state_skip_pager = + priv->wm_state_skip_pager = (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->skip_pager); @@ -890,7 +926,7 @@ meta_window_x11_client_message (MetaWindow *window, if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR || second == display->atom__NET_WM_STATE_SKIP_TASKBAR) { - window->wm_state_skip_taskbar = + priv->wm_state_skip_taskbar = (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar); diff --git a/src/core/window-x11.h b/src/core/window-x11.h index 81debec6c..29d95b0f5 100644 --- a/src/core/window-x11.h +++ b/src/core/window-x11.h @@ -26,6 +26,20 @@ #include #include +G_BEGIN_DECLS + +#define META_TYPE_WINDOW_X11 (meta_window_x11_get_type()) +#define META_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_X11, MetaWindowX11)) +#define META_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_X11, MetaWindowX11Class)) +#define META_IS_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_X11)) +#define META_IS_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_X11)) +#define META_WINDOW_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_X11, MetaWindowX11Class)) + +GType meta_window_x11_get_type (void); + +typedef struct _MetaWindowX11 MetaWindowX11; +typedef struct _MetaWindowX11Class MetaWindowX11Class; + void meta_window_x11_set_net_wm_state (MetaWindow *window); void meta_window_x11_set_wm_state (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index bffb70631..8b452b42f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -208,6 +208,15 @@ prefs_changed_callback (MetaPreference pref, } } +static void +meta_window_real_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + *skip_taskbar_out = FALSE; + *skip_pager_out = FALSE; +} + static void meta_window_finalize (GObject *object) { @@ -365,6 +374,8 @@ meta_window_class_init (MetaWindowClass *klass) object_class->get_property = meta_window_get_property; object_class->set_property = meta_window_set_property; + klass->get_default_skip_hints = meta_window_real_get_default_skip_hints; + g_object_class_install_property (object_class, PROP_TITLE, g_param_spec_string ("title", @@ -757,7 +768,10 @@ _meta_window_shared_new (MetaDisplay *display, "IsUnviewable" : "(unknown)"); - window = g_object_new (META_TYPE_WINDOW, NULL); + if (client_type == META_WINDOW_CLIENT_TYPE_X11) + window = g_object_new (META_TYPE_WINDOW_X11, NULL); + else + window = g_object_new (META_TYPE_WINDOW, NULL); window->constructing = TRUE; @@ -909,8 +923,6 @@ _meta_window_shared_new (MetaDisplay *display, window->wm_state_modal = FALSE; window->skip_taskbar = FALSE; window->skip_pager = FALSE; - window->wm_state_skip_taskbar = FALSE; - window->wm_state_skip_pager = FALSE; window->wm_state_above = FALSE; window->wm_state_below = FALSE; window->wm_state_demands_attention = FALSE; @@ -7160,6 +7172,14 @@ set_allowed_actions_hint (MetaWindow *window) #undef MAX_N_ACTIONS } +static void +meta_window_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + META_WINDOW_GET_CLASS (window)->get_default_skip_hints (window, skip_taskbar_out, skip_pager_out); +} + static void meta_window_recalc_skip_features (MetaWindow *window) { @@ -7194,8 +7214,12 @@ meta_window_recalc_skip_features (MetaWindow *window) break; case META_WINDOW_NORMAL: - window->skip_taskbar = window->wm_state_skip_taskbar; - window->skip_pager = window->wm_state_skip_pager; + { + gboolean skip_taskbar_hint, skip_pager_hint; + meta_window_get_default_skip_hints (window, &skip_taskbar_hint, &skip_pager_hint); + window->skip_taskbar = skip_taskbar_hint; + window->skip_pager = skip_pager_hint; + } break; } }