Commit dc5bb38a authored by Christoph Haag's avatar Christoph Haag Committed by Lubosz Sarnecki

window: dynamically allocate XrdWindowData & persist during overlay scene switch

parent 30930287
......@@ -146,6 +146,11 @@ _desktop_window_process_frame (Example *self, DesktopWindow *desktop_window)
{
XrdWindow *xrd_window = xrd_client_lookup_window (self->client,
desktop_window);
if (!xrd_window)
{
g_print ("Error processing frame, window is NULL\n");
return TRUE;
}
WindowWrapper *window_wrapper;
g_object_get (xrd_window, "native", &window_wrapper, NULL);
......@@ -393,6 +398,8 @@ _cleanup (Example *self)
WindowWrapper *example_window;
g_object_get (window, "native", &example_window, NULL);
g_object_unref (example_window->gulkan_texture);
xrd_window_close (window);
}
g_object_unref (self->window_pixbuf);
......
......@@ -18,7 +18,7 @@ struct _XrdOverlayWindow
OpenVROverlay parent;
gboolean recreate;
XrdWindowData window_data;
XrdWindowData *window_data;
};
enum
......@@ -50,27 +50,27 @@ xrd_overlay_window_set_property (GObject *object,
switch (property_id)
{
case PROP_TITLE:
if (self->window_data.title)
g_string_free (self->window_data.title, TRUE);
self->window_data.title = g_string_new (g_value_get_string (value));
if (self->window_data->title)
g_string_free (self->window_data->title, TRUE);
self->window_data->title = g_string_new (g_value_get_string (value));
break;
case PROP_SCALE:
self->window_data.scale = g_value_get_float (value);
self->window_data->scale = g_value_get_float (value);
break;
case PROP_NATIVE:
self->window_data.native = g_value_get_pointer (value);
self->window_data->native = g_value_get_pointer (value);
break;
case PROP_TEXTURE_WIDTH:
self->window_data.texture_width = g_value_get_uint (value);
self->window_data->texture_width = g_value_get_uint (value);
break;
case PROP_TEXTURE_HEIGHT:
self->window_data.texture_height = g_value_get_uint (value);
self->window_data->texture_height = g_value_get_uint (value);
break;
case PROP_WIDTH_METERS:
self->window_data.initial_size_meters.x = g_value_get_float (value);
self->window_data->initial_size_meters.x = g_value_get_float (value);
break;
case PROP_HEIGHT_METERS:
self->window_data.initial_size_meters.y = g_value_get_float (value);
self->window_data->initial_size_meters.y = g_value_get_float (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
......@@ -89,25 +89,25 @@ xrd_overlay_window_get_property (GObject *object,
switch (property_id)
{
case PROP_TITLE:
g_value_set_string (value, self->window_data.title->str);
g_value_set_string (value, self->window_data->title->str);
break;
case PROP_SCALE:
g_value_set_float (value, self->window_data.scale);
g_value_set_float (value, self->window_data->scale);
break;
case PROP_NATIVE:
g_value_set_pointer (value, self->window_data.native);
g_value_set_pointer (value, self->window_data->native);
break;
case PROP_TEXTURE_WIDTH:
g_value_set_uint (value, self->window_data.texture_width);
g_value_set_uint (value, self->window_data->texture_width);
break;
case PROP_TEXTURE_HEIGHT:
g_value_set_uint (value, self->window_data.texture_height);
g_value_set_uint (value, self->window_data->texture_height);
break;
case PROP_WIDTH_METERS:
g_value_set_float (value, self->window_data.initial_size_meters.x);
g_value_set_float (value, self->window_data->initial_size_meters.x);
break;
case PROP_HEIGHT_METERS:
g_value_set_float (value, self->window_data.initial_size_meters.y);
g_value_set_float (value, self->window_data->initial_size_meters.y);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
......@@ -129,7 +129,7 @@ _update_dimensions (XrdOverlayWindow *self)
openvr_overlay_set_mouse_scale (OPENVR_OVERLAY (self), w, h);
if (self->window_data.child_window)
if (self->window_data->child_window)
xrd_window_update_child (XRD_WINDOW (self));
}
......@@ -177,8 +177,14 @@ _set_transformation (XrdWindow *window,
XrdOverlayWindow *self = XRD_OVERLAY_WINDOW (window);
gboolean res =
openvr_overlay_set_transform_absolute (OPENVR_OVERLAY (self), mat);
if (self->window_data.child_window)
if (self->window_data->child_window)
xrd_window_update_child (window);
XrdWindowData *data = xrd_window_get_data (window);
graphene_matrix_t transform_unscaled;
xrd_window_get_transformation_no_scale (window, &transform_unscaled);
graphene_matrix_init_from_matrix (&data->transform, &transform_unscaled);
return res;
}
......@@ -242,7 +248,10 @@ _submit_texture (XrdWindow *window,
guint new_width = gulkan_texture_get_width (texture);
guint new_height = gulkan_texture_get_height (texture);
if (current_width != new_width || current_height != new_height)
/* update overlay if there is no texture, even if the texture dims
* are already the same */
if (!self->window_data->texture ||
current_width != new_width || current_height != new_height)
{
g_object_set (self,
"texture-width", new_width,
......@@ -262,10 +271,10 @@ _submit_texture (XrdWindow *window,
openvr_overlay_submit_texture (OPENVR_OVERLAY (self), client, texture);
/* let the previous texture stay alive until this one has been submitted */
if (self->window_data.texture)
g_object_unref (self->window_data.texture);
self->window_data.texture = texture;
g_object_ref (self->window_data.texture);
if (self->window_data->texture)
g_object_unref (self->window_data->texture);
self->window_data->texture = texture;
g_object_ref (self->window_data->texture);
}
static void
......@@ -289,15 +298,18 @@ _poll_event (XrdWindow *window)
static void
xrd_overlay_window_init (XrdOverlayWindow *self)
{
self->window_data.title = NULL;
self->window_data.child_window = NULL;
self->window_data.parent_window = NULL;
self->window_data.native = NULL;
self->window_data.texture_width = 0;
self->window_data.texture_height = 0;
self->window_data.texture = NULL;
self->window_data.selected = FALSE;
graphene_matrix_init_identity (&self->window_data.reset_transform);
self->window_data = g_malloc (sizeof (XrdWindowData));
self->window_data->title = NULL;
self->window_data->child_window = NULL;
self->window_data->parent_window = NULL;
self->window_data->native = NULL;
self->window_data->texture_width = 0;
self->window_data->texture_height = 0;
self->window_data->texture = NULL;
self->window_data->selected = FALSE;
self->window_data->xrd_window = XRD_WINDOW (self);
self->window_data->pinned = FALSE;
graphene_matrix_init_identity (&self->window_data->reset_transform);
}
/** xrd_overlay_window_new:
......@@ -328,6 +340,21 @@ xrd_overlay_window_new_from_meters (const gchar *title,
return window;
}
XrdOverlayWindow *
xrd_overlay_window_new_from_data (XrdWindowData *data)
{
XrdOverlayWindow *window =
(XrdOverlayWindow*) g_object_new (XRD_TYPE_OVERLAY_WINDOW, NULL);
// TODO: avoid unnecessary allocation
g_free (window->window_data);
window->window_data = data;
_set_transformation (XRD_WINDOW (window), &data->transform);
return window;
}
XrdOverlayWindow *
xrd_overlay_window_new_from_pixels (const gchar *title,
......@@ -380,7 +407,7 @@ xrd_overlay_window_constructed (GObject *gobject)
g_sprintf (overlay_id_str, "xrd-window-%d", iface->windows_created);
openvr_overlay_create (OPENVR_OVERLAY (self), overlay_id_str,
self->window_data.title->str);
self->window_data->title->str);
/* g_print ("Created overlay %s\n", overlay_id_str); */
......@@ -404,23 +431,6 @@ xrd_overlay_window_constructed (GObject *gobject)
static void
xrd_overlay_window_finalize (GObject *gobject)
{
XrdOverlayWindow *self = XRD_OVERLAY_WINDOW (gobject);
XrdOverlayWindow *parent =
XRD_OVERLAY_WINDOW (self->window_data.parent_window);
if (parent != NULL)
parent->window_data.child_window = NULL;
XrdOverlayWindow *child = XRD_OVERLAY_WINDOW (self->window_data.child_window);
if (child)
child->window_data.parent_window = NULL;
if (self->window_data.texture)
g_object_unref (self->window_data.texture);
g_string_free (self->window_data.title, TRUE);
G_OBJECT_CLASS (xrd_overlay_window_parent_class)->finalize (gobject);
}
......@@ -428,7 +438,7 @@ static XrdWindowData*
_get_data (XrdWindow *window)
{
XrdOverlayWindow *self = XRD_OVERLAY_WINDOW (window);
return &self->window_data;
return self->window_data;
}
static void
......
......@@ -34,6 +34,9 @@ xrd_overlay_window_new_from_meters (const gchar *title,
float height,
float ppm);
XrdOverlayWindow *
xrd_overlay_window_new_from_data (XrdWindowData *data);
XrdOverlayWindow *
xrd_overlay_window_new_from_pixels (const gchar *title,
uint32_t width,
......
......@@ -45,7 +45,7 @@ typedef struct _XrdSceneWindowPrivate
GulkanUniformBuffer *shading_buffer;
XrdWindowUniformBuffer shading_buffer_data;
XrdWindowData window_data;
XrdWindowData *window_data;
} XrdSceneWindowPrivate;
G_DEFINE_TYPE_WITH_CODE (XrdSceneWindow, xrd_scene_window, XRD_TYPE_SCENE_OBJECT,
......@@ -65,27 +65,27 @@ xrd_scene_window_set_property (GObject *object,
switch (property_id)
{
case PROP_TITLE:
if (priv->window_data.title)
g_string_free (priv->window_data.title, TRUE);
priv->window_data.title = g_string_new (g_value_get_string (value));
if (priv->window_data->title)
g_string_free (priv->window_data->title, TRUE);
priv->window_data->title = g_string_new (g_value_get_string (value));
break;
case PROP_SCALE:
priv->window_data.scale = g_value_get_float (value);
priv->window_data->scale = g_value_get_float (value);
break;
case PROP_NATIVE:
priv->window_data.native = g_value_get_pointer (value);
priv->window_data->native = g_value_get_pointer (value);
break;
case PROP_TEXTURE_WIDTH:
priv->window_data.texture_width = g_value_get_uint (value);
priv->window_data->texture_width = g_value_get_uint (value);
break;
case PROP_TEXTURE_HEIGHT:
priv->window_data.texture_height = g_value_get_uint (value);
priv->window_data->texture_height = g_value_get_uint (value);
break;
case PROP_WIDTH_METERS:
priv->window_data.initial_size_meters.x = g_value_get_float (value);
priv->window_data->initial_size_meters.x = g_value_get_float (value);
break;
case PROP_HEIGHT_METERS:
priv->window_data.initial_size_meters.y = g_value_get_float (value);
priv->window_data->initial_size_meters.y = g_value_get_float (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
......@@ -105,25 +105,25 @@ xrd_scene_window_get_property (GObject *object,
switch (property_id)
{
case PROP_TITLE:
g_value_set_string (value, priv->window_data.title->str);
g_value_set_string (value, priv->window_data->title->str);
break;
case PROP_SCALE:
g_value_set_float (value, priv->window_data.scale);
g_value_set_float (value, priv->window_data->scale);
break;
case PROP_NATIVE:
g_value_set_pointer (value, priv->window_data.native);
g_value_set_pointer (value, priv->window_data->native);
break;
case PROP_TEXTURE_WIDTH:
g_value_set_uint (value, priv->window_data.texture_width);
g_value_set_uint (value, priv->window_data->texture_width);
break;
case PROP_TEXTURE_HEIGHT:
g_value_set_uint (value, priv->window_data.texture_height);
g_value_set_uint (value, priv->window_data->texture_height);
break;
case PROP_WIDTH_METERS:
g_value_set_float (value, priv->window_data.initial_size_meters.x);
g_value_set_float (value, priv->window_data->initial_size_meters.x);
break;
case PROP_HEIGHT_METERS:
g_value_set_float (value, priv->window_data.initial_size_meters.y);
g_value_set_float (value, priv->window_data->initial_size_meters.y);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
......@@ -157,22 +157,26 @@ static void
xrd_scene_window_init (XrdSceneWindow *self)
{
XrdSceneWindowPrivate *priv = xrd_scene_window_get_instance_private (self);
priv->window_data = g_malloc (sizeof (XrdWindowData));
priv->vertex_buffer = gulkan_vertex_buffer_new ();
priv->sampler = VK_NULL_HANDLE;
priv->aspect_ratio = 1.0;
priv->window_data.texture = NULL;
priv->window_data->texture = NULL;
priv->shading_buffer = gulkan_uniform_buffer_new ();
priv->shading_buffer_data.flip_y = false;
priv->window_data.title = NULL;
priv->window_data.child_window = NULL;
priv->window_data.parent_window = NULL;
priv->window_data.native = NULL;
priv->window_data.texture_width = 0;
priv->window_data.texture_height = 0;
priv->window_data.texture = NULL;
priv->window_data.selected = FALSE;
graphene_matrix_init_identity (&priv->window_data.reset_transform);
priv->window_data->title = NULL;
priv->window_data->child_window = NULL;
priv->window_data->parent_window = NULL;
priv->window_data->native = NULL;
priv->window_data->texture_width = 0;
priv->window_data->texture_height = 0;
priv->window_data->texture = NULL;
priv->window_data->selected = FALSE;
priv->window_data->xrd_window = XRD_WINDOW (self);
priv->window_data->pinned = FALSE;
graphene_matrix_init_identity (&priv->window_data->reset_transform);
}
XrdSceneWindow *
......@@ -198,6 +202,26 @@ xrd_scene_window_new_from_meters (const gchar *title,
return window;
}
static gboolean
_set_transformation (XrdWindow *window,
graphene_matrix_t *mat);
XrdSceneWindow *
xrd_scene_window_new_from_data (XrdWindowData *data)
{
XrdSceneWindow *window = xrd_scene_window_new (data->title->str);
XrdSceneWindowPrivate *priv = xrd_scene_window_get_instance_private (window);
// TODO: avoid unnecessary allocation
g_free (priv->window_data);
priv->window_data = data;
_set_transformation (XRD_WINDOW (window), &data->transform);
return window;
}
XrdSceneWindow *
xrd_scene_window_new_from_pixels (const gchar *title,
uint32_t width,
......@@ -240,37 +264,11 @@ xrd_scene_window_finalize (GObject *gobject)
//g_object_unref (self->texture);
XrdSceneRenderer *renderer = xrd_scene_renderer_get_instance ();
vkDestroySampler (gulkan_client_get_device_handle (GULKAN_CLIENT (renderer)),
priv->sampler, NULL);
g_object_unref (priv->vertex_buffer);
XrdSceneWindow *parent =
XRD_SCENE_WINDOW (priv->window_data.parent_window);
if (parent != NULL)
{
XrdSceneWindowPrivate *parent_priv =
xrd_scene_window_get_instance_private (parent);
parent_priv->window_data.child_window = NULL;
}
XrdSceneWindow *child = XRD_SCENE_WINDOW (priv->window_data.child_window);
if (child)
{
XrdSceneWindowPrivate *child_priv =
xrd_scene_window_get_instance_private (child);
child_priv->window_data.parent_window = NULL;
}
if (priv->window_data.texture)
g_object_unref (priv->window_data.texture);
g_object_unref (priv->shading_buffer);
g_string_free (priv->window_data.title, TRUE);
G_OBJECT_CLASS (xrd_scene_window_parent_class)->finalize (gobject);
}
......@@ -325,7 +323,7 @@ xrd_scene_window_draw (XrdSceneWindow *self,
graphene_matrix_t *vp)
{
XrdSceneWindowPrivate *priv = xrd_scene_window_get_instance_private (self);
if (!priv->window_data.texture)
if (!priv->window_data->texture)
{
/* g_warning ("Trying to draw window with no texture.\n"); */
return;
......@@ -396,7 +394,7 @@ xrd_scene_window_update_descriptors (XrdSceneWindow *self)
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &(VkDescriptorImageInfo) {
.sampler = priv->sampler,
.imageView = gulkan_texture_get_image_view (priv->window_data.texture),
.imageView = gulkan_texture_get_image_view (priv->window_data->texture),
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
},
.pBufferInfo = NULL,
......@@ -436,9 +434,14 @@ _set_transformation (XrdWindow *window,
xrd_scene_object_set_scale (XRD_SCENE_OBJECT (self), height_meters);
XrdSceneWindowPrivate *priv = xrd_scene_window_get_instance_private (self);
if (priv->window_data.child_window)
if (priv->window_data->child_window)
xrd_window_update_child (window);
XrdWindowData *data = xrd_window_get_data (window);
graphene_matrix_t transform_unscaled;
xrd_window_get_transformation_no_scale (window, &transform_unscaled);
graphene_matrix_init_from_matrix (&data->transform, &transform_unscaled);
return TRUE;
}
......@@ -468,7 +471,7 @@ _submit_texture (XrdWindow *window,
XrdSceneWindow *self = XRD_SCENE_WINDOW (window);
XrdSceneWindowPrivate *priv = xrd_scene_window_get_instance_private (self);
if (texture == priv->window_data.texture)
if (texture == priv->window_data->texture)
{
gchar *title;
g_object_get (window, "title", &title, NULL);
......@@ -497,11 +500,11 @@ _submit_texture (XrdWindow *window,
gulkan_vertex_buffer_map_array (priv->vertex_buffer);
}
if (priv->window_data.texture)
g_object_unref (priv->window_data.texture);
if (priv->window_data->texture)
g_object_unref (priv->window_data->texture);
priv->window_data.texture = texture;
g_object_ref (priv->window_data.texture);
priv->window_data->texture = texture;
g_object_ref (priv->window_data->texture);
guint mip_levels = gulkan_texture_get_mip_levels (texture);
......@@ -576,7 +579,7 @@ _get_data (XrdWindow *window)
{
XrdSceneWindow *self = XRD_SCENE_WINDOW (window);
XrdSceneWindowPrivate *priv = xrd_scene_window_get_instance_private (self);
return &priv->window_data;
return priv->window_data;
}
static void
......
......@@ -47,6 +47,9 @@ xrd_scene_window_new_from_meters (const gchar *title,
float height,
float ppm);
XrdSceneWindow *
xrd_scene_window_new_from_data (XrdWindowData *data);
XrdSceneWindow *
xrd_scene_window_new_from_pixels (const gchar *title,
uint32_t width,
......
......@@ -85,7 +85,7 @@ typedef struct _XrdClientPrivate
gboolean always_show_overlay_pointer;
/* for desktops to lookup an #XrdWindow */
/* maps a key to desktop #XrdWindows, but not buttons. */
GHashTable *window_mapping;
} XrdClientPrivate;
......@@ -218,7 +218,8 @@ xrd_client_add_window (XrdClient *self,
xrd_client_add_window_callbacks (self, window);
if (lookup_key != NULL)
g_hash_table_insert (priv->window_mapping, lookup_key, window);
g_hash_table_insert (priv->window_mapping, lookup_key,
xrd_window_get_data (window));
}
XrdWindow *
......@@ -226,7 +227,13 @@ xrd_client_lookup_window (XrdClient *self,
gpointer key)
{
XrdClientPrivate *priv = xrd_client_get_instance_private (self);
return g_hash_table_lookup (priv->window_mapping, key);
XrdWindowData *data = g_hash_table_lookup (priv->window_mapping, key);
if (!data)
{
g_print ("Error looking up window %p\n", key);
return NULL;
}
return data->xrd_window;
}
/**
......@@ -366,6 +373,8 @@ xrd_client_show_pinned_only (XrdClient *self,
GulkanClient *client = xrd_client_get_uploader (self);
VkImageLayout layout = xrd_client_get_upload_layout (self);
if (priv->button_pinned_only)
{
if (pinned_only)
{
xrd_button_set_icon (priv->button_pinned_only, client, layout,
......@@ -376,6 +385,7 @@ xrd_client_show_pinned_only (XrdClient *self,
xrd_button_set_icon (priv->button_pinned_only, client, layout,
"/icons/object-visible-symbolic.svg");
}
}
}
static void
......@@ -600,6 +610,10 @@ xrd_client_remove_window (XrdClient *self,
XrdWindow *window)
{
XrdClientPrivate *priv = xrd_client_get_instance_private (self);
g_hash_table_foreach_remove (priv->window_mapping, _match_value_ptr,
xrd_window_get_data (window));
xrd_window_manager_remove_window (priv->manager, window);
GList *controllers = g_hash_table_get_values (priv->controllers);
......@@ -623,8 +637,6 @@ xrd_client_remove_window (XrdClient *self,
xrd_controller_reset_grab_state (controller);
}
g_list_free(controllers);
g_hash_table_foreach_remove (priv->window_mapping, _match_value_ptr, window);
}
OpenVRActionSet *
......@@ -1733,6 +1745,23 @@ xrd_client_window_new_from_meters (XrdClient *client,
return window;
}
static XrdWindow *
xrd_client_window_new_from_data (XrdClient *client,
XrdWindowData *data)
{
XrdWindow *window;
if (XRD_IS_SCENE_CLIENT (client))
{
window = XRD_WINDOW (xrd_scene_window_new_from_data (data));
xrd_scene_window_initialize (XRD_SCENE_WINDOW (window));
}
else
{
window = XRD_WINDOW (xrd_overlay_window_new_from_data (data));
}
return window;
}
XrdWindow *
xrd_client_window_new_from_pixels (XrdClient *client,
const char *title,
......@@ -1947,8 +1976,7 @@ xrd_client_init (XrdClient *self)
priv->controllers = g_hash_table_new_full (g_int64_hash, g_int64_equal,
g_free, g_object_unref);
priv->window_mapping = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_object_unref);
priv->window_mapping = g_hash_table_new (g_direct_hash, g_direct_equal);
xrd_settings_connect_and_apply (G_CALLBACK (xrd_settings_update_double_val),
"scroll-to-push-ratio",
......@@ -2154,9 +2182,6 @@ _replace_client (XrdClient *self)
XrdClient *ret = NULL;
gboolean to_scene = XRD_IS_OVERLAY_CLIENT (self);
XrdClientPrivate *priv = xrd_client_get_instance_private (self);
g_hash_table_destroy (priv->window_mapping);
if (to_scene)
{
g_object_unref (self);
......@@ -2169,80 +2194,33 @@ _replace_client (XrdClient *self)
g_object_unref (self);
ret = XRD_CLIENT (xrd_overlay_client_new ());
}
XrdClientPrivate *ret_priv = xrd_client_get_instance_private (ret);
ret_priv->window_mapping =
g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_object_unref);
return ret;
}
static gpointer *
_g_hash_table_reverse_lookup (GHashTable *hash_table, XrdWindow *find)
static void
_insert_into_new_hash_table (gpointer key,
gpointer value,
gpointer new_hash_table)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, hash_table);
while (g_hash_table_iter_next (&iter, &key, &value))
{
if (value == find)
return key;
}
return NULL;
g_hash_table_insert (new_hash_table, key, value);
}
static void
_save_window_states (XrdClient *self,
XrdWindowState *state,
gpointer *lookup_keys,
int window_count)
static GHashTable *
_g_hash_table_clone_direct (GHashTable *old_table)
{
XrdWindowManager *manager = xrd_client_get_manager (self);
GSList *windows = xrd_window_manager_get_windows (manager);
for (int i = 0; i < window_count; i++)
{
state[i].child_index = -1;
XrdWindow *window = g_slist_nth_data (windows, (guint)i);
XrdClientPrivate *priv = xrd_client_get_instance_private (self);
lookup_keys[i] = _g_hash_table_reverse_lookup (priv->window_mapping,
window);
XrdWindowData *data = xrd_window_get_data (window);
state[i].pinned = data->pinned;
xrd_window_get_reset_transformation (window, &state[i].reset_transform);
/* Window state is saved in the order windows were added to the client.
* So the reference to a child window is just an index in this array. */
if (data->child_window)
{
state[i].child_index = g_slist_index (windows, data->child_window);
graphene_point_init_from_point (&state[i].child_offset_center,
&data->child_offset_center);
}
/* Window with parent window is child and is not draggable */
state[i].is_draggable = data->parent_window == NULL;
g_object_get (window,
"native", &state[i].native,
"title", &state[i].title,
"scale", &state[i].scale,
"initial-width-meters", &state[i].initial_width,
"initial-height-meters", &state[i].initial_height,
"texture-width", &state[i].texture_width,
"texture-height", &state[i].texture_height,
NULL);
GHashTable *new_table = g_hash_table_new (g_direct_hash, g_direct_equal);
g_hash_table_foreach (old_table, _insert_into_new_hash_table, new_table);
return new_table;
}
state[i].current_width = xrd_window_get_current_width_meters (window);
state[i].current_height = xrd_window_get_current_height_meters (window);
xrd_window_get_transformation_no_scale (window, &state[i].transform);
}
static GSList *
_get_new_window_data_list (XrdClient *self)
{
GSList *data = NULL;
GSList *windows = xrd_client_get_windows (self);
for (GSList *l = windows; l; l = l->next)
data = g_slist_append (data, xrd_window_get_data (l->data));
return data;
}
/**
......@@ -2258,8 +2236,8 @@ _save_window_states (XrdClient *self,
*
* The caller is responsible for reconnecting callbacks to #XrdClient signals.
* The caller is responsible to not use references to any previous #XrdWindow.
* The caller may use xrd_client_get_windows() to get the list of new windows
* and may use the "native" property to recognize each window.
* Pointers to #XrdWindowData will remain valid, however
* #XrdWindowData->xrd_window will point to a new #XrdWindow.
*
* Returns: A new #XrdClient of the opposite mode than the passed one.
*/
......@@ -2267,73 +2245,41 @@ struct _XrdClient *
xrd_client_switch_mode (XrdClient *self)
{
XrdClientPrivate *priv = xrd_client_get_instance_private (self);
gboolean show_only_pinned = priv->pinned_only;
gboolean ignore_input = priv->ignore_input;
XrdWindowManager *manager = xrd_client_get_manager (self