backends: Add simple object to delegate logical monitor layout queries

This object can be passed to random places, and be trusted to remain unchanged
till replaced. Makes it an ideal replacement for MetaMonitorManager across
threads.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
This commit is contained in:
Carlos Garnacho 2020-07-16 13:52:39 +02:00 committed by Marge Bot
parent b1d12a994d
commit 0c1d48bd08
5 changed files with 282 additions and 0 deletions

View File

@ -31,6 +31,7 @@
#include "backends/meta-cursor.h" #include "backends/meta-cursor.h"
#include "backends/meta-display-config-shared.h" #include "backends/meta-display-config-shared.h"
#include "backends/meta-monitor-transform.h" #include "backends/meta-monitor-transform.h"
#include "backends/meta-viewport-info.h"
#include "core/util-private.h" #include "core/util-private.h"
#include "meta/display.h" #include "meta/display.h"
#include "meta/meta-monitor-manager.h" #include "meta/meta-monitor-manager.h"
@ -404,4 +405,6 @@ meta_find_output_assignment (MetaOutputAssignment **outputs,
void meta_monitor_manager_post_init (MetaMonitorManager *manager); void meta_monitor_manager_post_init (MetaMonitorManager *manager);
MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manager);
#endif /* META_MONITOR_MANAGER_PRIVATE_H */ #endif /* META_MONITOR_MANAGER_PRIVATE_H */

View File

@ -3250,3 +3250,37 @@ meta_monitor_manager_post_init (MetaMonitorManager *manager)
G_CALLBACK (update_panel_orientation_managed), manager, G_CALLBACK (update_panel_orientation_managed), manager,
G_CONNECT_SWAPPED); G_CONNECT_SWAPPED);
} }
MetaViewportInfo *
meta_monitor_manager_get_viewports (MetaMonitorManager *manager)
{
MetaViewportInfo *info;
GArray *views, *scales;
GList *logical_monitors, *l;
views = g_array_new (FALSE, FALSE, sizeof (cairo_rectangle_int_t));
scales = g_array_new (FALSE, FALSE, sizeof (float));
logical_monitors = meta_monitor_manager_get_logical_monitors (manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
cairo_rectangle_int_t rect;
float scale;
rect = logical_monitor->rect;
g_array_append_val (views, rect);
scale = logical_monitor->scale;
g_array_append_val (scales, scale);
}
info = meta_viewport_info_new ((cairo_rectangle_int_t *) views->data,
(float *) scales->data,
views->len);
g_array_unref (views);
g_array_unref (scales);
return info;
}

View File

@ -0,0 +1,189 @@
/*
* Copyright (C) 2020 Red Hat
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Carlos Garnacho <carlosg@gnome.org>
*/
#include "config.h"
#include "backends/meta-viewport-info.h"
#include "core/main-private.h"
#include "core/boxes-private.h"
typedef struct _ViewInfo ViewInfo;
struct _ViewInfo
{
MetaRectangle rect;
float scale;
};
struct _MetaViewportInfo
{
GObject parent;
GArray *views;
};
G_DEFINE_TYPE (MetaViewportInfo, meta_viewport_info, G_TYPE_OBJECT)
static void
meta_viewport_info_finalize (GObject *object)
{
MetaViewportInfo *info = META_VIEWPORT_INFO (object);
g_array_unref (info->views);
G_OBJECT_CLASS (meta_viewport_info_parent_class)->finalize (object);
}
static void
meta_viewport_info_class_init (MetaViewportInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_viewport_info_finalize;
}
static void
meta_viewport_info_init (MetaViewportInfo *info)
{
info->views = g_array_new (FALSE, FALSE, sizeof (ViewInfo));
}
MetaViewportInfo *
meta_viewport_info_new (cairo_rectangle_int_t *views,
float *scales,
int n_views)
{
MetaViewportInfo *viewport_info;
int i;
viewport_info = g_object_new (META_TYPE_VIEWPORT_INFO, NULL);
for (i = 0; i < n_views; i++)
{
ViewInfo info;
info.rect = views[i];
info.scale = scales[i];
g_array_append_val (viewport_info->views, info);
}
return viewport_info;
}
int
meta_viewport_info_get_view_at (MetaViewportInfo *viewport_info,
float x,
float y)
{
int i;
for (i = 0; i < viewport_info->views->len; i++)
{
ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
if (META_POINT_IN_RECT (x, y, info->rect))
return i;
}
return -1;
}
gboolean
meta_viewport_info_get_view_info (MetaViewportInfo *viewport_info,
int idx,
cairo_rectangle_int_t *rect,
float *scale)
{
ViewInfo *info;
if (idx < 0 || idx >= viewport_info->views->len)
return FALSE;
info = &g_array_index (viewport_info->views, ViewInfo, idx);
if (rect)
*rect = info->rect;
if (scale)
*scale = info->scale;
return TRUE;
}
static gboolean
view_has_neighbor (cairo_rectangle_int_t *view,
cairo_rectangle_int_t *neighbor,
MetaDisplayDirection neighbor_direction)
{
switch (neighbor_direction)
{
case META_DISPLAY_RIGHT:
if (neighbor->x == (view->x + view->width) &&
meta_rectangle_vert_overlap (neighbor, view))
return TRUE;
break;
case META_DISPLAY_LEFT:
if (view->x == (neighbor->x + neighbor->width) &&
meta_rectangle_vert_overlap (neighbor, view))
return TRUE;
break;
case META_DISPLAY_UP:
if (view->y == (neighbor->y + neighbor->height) &&
meta_rectangle_horiz_overlap (neighbor, view))
return TRUE;
break;
case META_DISPLAY_DOWN:
if (neighbor->y == (view->y + view->height) &&
meta_rectangle_horiz_overlap (neighbor, view))
return TRUE;
break;
}
return FALSE;
}
int
meta_viewport_info_get_neighbor (MetaViewportInfo *viewport_info,
int idx,
MetaDisplayDirection direction)
{
cairo_rectangle_int_t rect;
int i;
if (!meta_viewport_info_get_view_info (viewport_info, idx, &rect, NULL))
return -1;
for (i = 0; i < viewport_info->views->len; i++)
{
ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
if (idx == i)
continue;
if (view_has_neighbor (&rect, &info->rect, direction))
return i;
}
return -1;
}
int
meta_viewport_info_get_num_views (MetaViewportInfo *info)
{
return info->views->len;
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2020 Red Hat
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Carlos Garnacho <carlosg@gnome.org>
*/
#ifndef META_VIEWPORT_INFO_H
#define META_VIEWPORT_INFO_H
#include <cairo.h>
#include <glib-object.h>
#include "meta/display.h"
#define META_TYPE_VIEWPORT_INFO (meta_viewport_info_get_type ())
G_DECLARE_FINAL_TYPE (MetaViewportInfo, meta_viewport_info,
META, VIEWPORT_INFO, GObject)
MetaViewportInfo * meta_viewport_info_new (cairo_rectangle_int_t *views,
float *scales,
int n_views);
int meta_viewport_info_get_view_at (MetaViewportInfo *info,
float x,
float y);
gboolean meta_viewport_info_get_view_info (MetaViewportInfo *viewport_info,
int idx,
cairo_rectangle_int_t *rect,
float *scale);
int meta_viewport_info_get_neighbor (MetaViewportInfo *info,
int idx,
MetaDisplayDirection direction);
int meta_viewport_info_get_num_views (MetaViewportInfo *info);
#endif /* META_VIEWPORT_INFO_H */

View File

@ -233,6 +233,8 @@ mutter_sources = [
'backends/meta-settings-private.h', 'backends/meta-settings-private.h',
'backends/meta-stage.c', 'backends/meta-stage.c',
'backends/meta-stage-private.h', 'backends/meta-stage-private.h',
'backends/meta-viewport-info.c',
'backends/meta-viewport-info.h',
'backends/x11/cm/meta-backend-x11-cm.c', 'backends/x11/cm/meta-backend-x11-cm.c',
'backends/x11/cm/meta-backend-x11-cm.h', 'backends/x11/cm/meta-backend-x11-cm.h',
'backends/x11/cm/meta-cursor-sprite-xfixes.c', 'backends/x11/cm/meta-cursor-sprite-xfixes.c',