Compare commits

...

12 Commits

Author SHA1 Message Date
Georges Basile Stavracas Neto
66910ab422 compositor: Introduce tile picker API
Plugins might want to know when they should show
a tile picker UI and, since we control the tiling
state from the window manager side, we just need
to tell the compositor when they should do that.

This commit adds the necessary plumbing to let the
compositor and plugins know when a tile picker should
be shown.
2017-12-29 14:12:25 -02:00
Georges Basile Stavracas Neto
17b56e9604 window: Export tiling as public API
So that consumers of Mutter APIs can monitor the tile
mode of any given window. This commit also adds the
tile mode as a property of the window.
2017-12-29 14:12:25 -02:00
Hans de Goede
5eacdf7af7 monitor-unit-tests: Add non upright panel test
https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
ca638d1354 monitor-unit-tests: Add support for panel-orientation
https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
f12e6ad4f1 monitor-config-manager: Adjust accelerometer rotation for panel-orientation
The device orientation coming out of iio-sensor-proxy defines upright/normal
as the direction in which the picture is displayed on the LCD panel without
any rotation. This is necessary for accelerometer rotation to work properly
in desktop environments which are not aware of panel-orientation issues.

This means that we need to correct the logical-monitor-config / user-visible
rotation for the panel-orientation when we get rotation info from
iio-sensor-proxy.

https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
0bbda3ad87 monitor-manager: Take panel-orientation into account for physical size
Just like we swap the x and y resolution of the monitor modes when
the panel-orientation requires 90 or 270 degree rotation to compensate,
we should do the same for the width and height in mm of the monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
dd43d04d42 monitor-manager: Add portrait modes to portrait displays
If a monitor's max resolution is a portrait resolution, then assume it is
a native portrait monitor and add portrait versions of the common modes.

https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
383ac76d00 cursor-renderer-native: Take panel-orientation into account
Even if the logical_monitor config does not have an active transform,
we might still be doing a transform under the hood to compensate for
panel-orientation. Check for this and fall back to the sw cursor if this
is the case.

https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
e59ca14f6c monitor-manager: Take panel orientation into account when getting input matrix
If a LCD panel has a non normal orientation (mounted upside-down or 90
degrees rotated) then the kernel will report touchscreen coordinates with
the origin matching the native (e.g. upside down) coordinates of the panel.

Since we transparently rotate the image on the panel to correct for the
non normal panel-orientation, we must apply the same transform to input
coordinates to keep the aligned.

https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
7917b083cb monitor-manager: Take drm-connector panel-orientation property into account
Some x86 clamshell design devices use portrait tablet LCD panels while
they should use a landscape panel, resoluting in a 90 degree rotated
picture.

Newer kernels detect this and rotate the fb console in software to
compensate. These kernels also export their knowledge of the LCD panel
orientation vs the casing in a "panel orientation" drm_connector property.

This commit adds support to mutter for reading the "panel orientation"
and transparently (from a mutter consumer's pov) fixing this by applying
a (hidden) rotation transform to compensate for the panel orientation.

Related: https://bugs.freedesktop.org/show_bug.cgi?id=94894

https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Hans de Goede
2b3040d04f monitor: s/meta_monitor_derived_derive_layout/meta_monitor_tiled_derive_layout/
Fix meta_monitor_derived_derive_layout typo.

https://bugzilla.gnome.org/show_bug.cgi?id=782294
2017-12-25 17:01:45 +08:00
Ting-Wei Lan
6cc48d8cbb build: Fix non-wayland builds
meta_dnd_wayland_handle_end_modal is not available on non-wayland build.

https://bugzilla.gnome.org/show_bug.cgi?id=791916
2017-12-24 17:55:14 +08:00
26 changed files with 531 additions and 111 deletions

View File

@@ -772,12 +772,11 @@ update_keyboard_repeat (MetaInputSettings *input_settings)
repeat, delay, interval);
}
static gboolean
logical_monitor_has_monitor (MetaMonitorManager *monitor_manager,
MetaLogicalMonitor *logical_monitor,
const char *vendor,
const char *product,
const char *serial)
static MetaMonitor *
logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor,
const char *vendor,
const char *product,
const char *serial)
{
GList *monitors;
GList *l;
@@ -790,20 +789,22 @@ logical_monitor_has_monitor (MetaMonitorManager *monitor_manager,
if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 &&
g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 &&
g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0)
return TRUE;
return monitor;
}
return FALSE;
return NULL;
}
static MetaLogicalMonitor *
meta_input_settings_find_logical_monitor (MetaInputSettings *input_settings,
GSettings *settings,
ClutterInputDevice *device)
static void
meta_input_settings_find_monitor (MetaInputSettings *input_settings,
GSettings *settings,
ClutterInputDevice *device,
MetaMonitor **out_monitor,
MetaLogicalMonitor **out_logical_monitor)
{
MetaInputSettingsPrivate *priv;
MetaMonitorManager *monitor_manager;
MetaLogicalMonitor *ret = NULL;
MetaMonitor *monitor;
guint n_values;
GList *logical_monitors;
GList *l;
@@ -831,20 +832,20 @@ meta_input_settings_find_logical_monitor (MetaInputSettings *input_settings,
{
MetaLogicalMonitor *logical_monitor = l->data;
if (logical_monitor_has_monitor (monitor_manager,
logical_monitor,
edid[0],
edid[1],
edid[2]))
monitor = logical_monitor_find_monitor (logical_monitor,
edid[0], edid[1], edid[2]);
if (monitor)
{
ret = logical_monitor;
if (out_monitor)
*out_monitor = monitor;
if (out_logical_monitor)
*out_logical_monitor = logical_monitor;
break;
}
}
out:
g_strfreev (edid);
return ret;
}
static void
@@ -880,9 +881,8 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings,
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE)
{
keep_aspect = g_settings_get_boolean (settings, "keep-aspect");
logical_monitor = meta_input_settings_find_logical_monitor (input_settings,
settings,
device);
meta_input_settings_find_monitor (input_settings, settings, device,
NULL, &logical_monitor);
}
else
{
@@ -901,7 +901,8 @@ update_device_display (MetaInputSettings *input_settings,
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 };
MetaLogicalMonitor *logical_monitor;
MetaMonitor *monitor = NULL;
MetaLogicalMonitor *logical_monitor = NULL;
if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE &&
clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE &&
@@ -916,15 +917,12 @@ update_device_display (MetaInputSettings *input_settings,
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE ||
clutter_input_device_get_mapping_mode (device) ==
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE)
logical_monitor = meta_input_settings_find_logical_monitor (input_settings,
settings,
device);
else
logical_monitor = NULL;
meta_input_settings_find_monitor (input_settings, settings, device,
&monitor, &logical_monitor);
if (logical_monitor)
if (monitor)
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
logical_monitor, matrix);
monitor, logical_monitor, matrix);
input_settings_class->set_matrix (input_settings, device, matrix);
@@ -1745,6 +1743,7 @@ MetaLogicalMonitor *
meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
ClutterInputDevice *device)
{
MetaLogicalMonitor *logical_monitor = NULL;
MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info;
@@ -1756,9 +1755,9 @@ meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
if (!info)
return NULL;
return meta_input_settings_find_logical_monitor (settings,
info->settings,
device);
meta_input_settings_find_monitor (settings, info->settings, device,
NULL, &logical_monitor);
return logical_monitor;
}
GDesktopTabletMapping
@@ -1862,7 +1861,7 @@ meta_input_settings_cycle_tablet_output (MetaInputSettings *input_settings,
{
MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info;
MetaLogicalMonitor *logical_monitor;
MetaLogicalMonitor *logical_monitor = NULL;
const gchar *edid[4] = { 0 }, *pretty_name = NULL;
g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
@@ -1885,9 +1884,9 @@ meta_input_settings_cycle_tablet_output (MetaInputSettings *input_settings,
}
#endif
logical_monitor = meta_input_settings_find_logical_monitor (input_settings,
info->settings,
device);
meta_input_settings_find_monitor (input_settings, info->settings, device,
NULL, &logical_monitor);
if (!cycle_logical_monitors (input_settings,
logical_monitor,
&logical_monitor))

View File

@@ -103,7 +103,8 @@ derive_monitor_transform (MetaMonitor *monitor)
main_output = meta_monitor_get_main_output (monitor);
return main_output->crtc->transform;
return meta_monitor_crtc_to_logical_transform (monitor,
main_output->crtc->transform);
}
MetaLogicalMonitor *

View File

@@ -152,11 +152,10 @@ assign_monitor_crtc (MetaMonitor *monitor,
}
transform = data->logical_monitor_config->transform;
if (meta_monitor_manager_is_transform_handled (data->monitor_manager,
crtc,
transform))
crtc_transform = transform;
else
crtc_transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
if (!meta_monitor_manager_is_transform_handled (data->monitor_manager,
crtc,
crtc_transform))
crtc_transform = META_MONITOR_TRANSFORM_NORMAL;
meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
@@ -755,6 +754,20 @@ create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager,
if (rotate)
transform = (current_logical_monitor_config->transform + 1) % META_MONITOR_TRANSFORM_FLIPPED;
else
{
/*
* The transform coming from the accelerometer should be applied to
* the crtc as is, without taking panel-orientation into account, this
* is done so that non panel-orientation aware desktop environments do the
* right thing. Mutter corrects for panel-orientation when applying the
* transform from a logical-monitor-config, so we must convert here.
*/
MetaMonitor *panel =
meta_monitor_manager_get_laptop_panel (config_manager->monitor_manager);
transform = meta_monitor_crtc_to_logical_transform (panel, transform);
}
if (current_logical_monitor_config->transform == transform)
return NULL;

View File

@@ -316,6 +316,7 @@ void meta_monitor_manager_read_current_state (MetaMonitorManager *
void meta_monitor_manager_on_hotplug (MetaMonitorManager *manager);
gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaLogicalMonitor *logical_monitor,
gfloat matrix[6]);
@@ -384,4 +385,11 @@ meta_monitor_transform_is_rotated (MetaMonitorTransform transform)
return (transform % 2);
}
/* Returns true if transform involves flipping */
static inline gboolean
meta_monitor_transform_is_flipped (MetaMonitorTransform transform)
{
return (transform >= META_MONITOR_TRANSFORM_FLIPPED);
}
#endif /* META_MONITOR_MANAGER_PRIVATE_H */

View File

@@ -2856,6 +2856,7 @@ multiply_matrix (float a[6],
gboolean
meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaLogicalMonitor *logical_monitor,
gfloat matrix[6])
{
@@ -2865,7 +2866,9 @@ meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
if (!calculate_viewport_matrix (manager, logical_monitor, viewport))
return FALSE;
/* Get transform corrected for LCD panel-orientation. */
transform = logical_monitor->transform;
transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
multiply_matrix (viewport, transform_matrices[transform],
matrix);
return TRUE;

View File

@@ -354,6 +354,37 @@ meta_monitor_get_connector_type (MetaMonitor *monitor)
return output->connector_type;
}
MetaMonitorTransform
meta_monitor_logical_to_crtc_transform (MetaMonitor *monitor,
MetaMonitorTransform transform)
{
MetaOutput *output = meta_monitor_get_main_output (monitor);
MetaMonitorTransform new_transform;
new_transform = (transform + output->panel_orientation_transform) %
META_MONITOR_TRANSFORM_FLIPPED;
if (meta_monitor_transform_is_flipped (transform))
new_transform += META_MONITOR_TRANSFORM_FLIPPED;
return new_transform;
}
MetaMonitorTransform
meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor,
MetaMonitorTransform transform)
{
MetaOutput *output = meta_monitor_get_main_output (monitor);
MetaMonitorTransform new_transform;
new_transform = (transform + META_MONITOR_TRANSFORM_FLIPPED -
output->panel_orientation_transform) %
META_MONITOR_TRANSFORM_FLIPPED;
if (meta_monitor_transform_is_flipped (transform))
new_transform += META_MONITOR_TRANSFORM_FLIPPED;
return new_transform;
}
static void
meta_monitor_finalize (GObject *object)
{
@@ -423,6 +454,29 @@ meta_monitor_add_mode (MetaMonitor *monitor,
return TRUE;
}
static MetaMonitorModeSpec
meta_monitor_create_spec (MetaMonitor *monitor,
int width,
int height,
MetaCrtcMode *crtc_mode)
{
MetaOutput *output = meta_monitor_get_main_output (monitor);
if (meta_monitor_transform_is_rotated (output->panel_orientation_transform))
{
int temp = width;
width = height;
height = temp;
}
return (MetaMonitorModeSpec) {
.width = width,
.height = height,
.refresh_rate = crtc_mode->refresh_rate,
.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS
};
}
static void
meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
{
@@ -443,12 +497,10 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
gboolean replace;
mode = g_new0 (MetaMonitorMode, 1);
mode->spec = (MetaMonitorModeSpec) {
.width = crtc_mode->width,
.height = crtc_mode->height,
.refresh_rate = crtc_mode->refresh_rate,
.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS
},
mode->spec = meta_monitor_create_spec (monitor,
crtc_mode->width,
crtc_mode->height,
crtc_mode);
mode->id = generate_mode_id (&mode->spec);
mode->crtc_modes = g_new (MetaMonitorCrtcMode, 1);
mode->crtc_modes[0] = (MetaMonitorCrtcMode) {
@@ -780,12 +832,8 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
mode->is_tiled = TRUE;
meta_monitor_tiled_calculate_tiled_size (monitor, &width, &height);
mode->parent.spec = (MetaMonitorModeSpec) {
.width = width,
.height = height,
.refresh_rate = reference_crtc_mode->refresh_rate,
.flags = reference_crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS
};
mode->parent.spec =
meta_monitor_create_spec (monitor, width, height, reference_crtc_mode);
mode->parent.id = generate_mode_id (&mode->parent.spec);
mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode,
@@ -895,12 +943,10 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
mode = g_new0 (MetaMonitorModeTiled, 1);
mode->is_tiled = FALSE;
mode->parent.spec = (MetaMonitorModeSpec) {
.width = crtc_mode->width,
.height = crtc_mode->height,
.refresh_rate = crtc_mode->refresh_rate,
.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS
};
mode->parent.spec = meta_monitor_create_spec (monitor,
crtc_mode->width,
crtc_mode->height,
crtc_mode);
mode->parent.id = generate_mode_id (&mode->parent.spec);
mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode,
g_list_length (monitor_priv->outputs));
@@ -1156,8 +1202,8 @@ meta_monitor_tiled_get_main_output (MetaMonitor *monitor)
}
static void
meta_monitor_derived_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout)
meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout)
{
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
@@ -1248,7 +1294,7 @@ meta_monitor_tiled_class_init (MetaMonitorTiledClass *klass)
object_class->finalize = meta_monitor_tiled_finalize;
monitor_class->get_main_output = meta_monitor_tiled_get_main_output;
monitor_class->derive_layout = meta_monitor_derived_derive_layout;
monitor_class->derive_layout = meta_monitor_tiled_derive_layout;
monitor_class->calculate_crtc_pos = meta_monitor_tiled_calculate_crtc_pos;
monitor_class->get_suggested_position = meta_monitor_tiled_get_suggested_position;
}

View File

@@ -145,6 +145,16 @@ const char * meta_monitor_get_serial (MetaMonitor *monitor);
MetaConnectorType meta_monitor_get_connector_type (MetaMonitor *monitor);
/* This function returns the transform corrected for the panel orientation */
MetaMonitorTransform meta_monitor_logical_to_crtc_transform (MetaMonitor *monitor,
MetaMonitorTransform transform);
/*
* This function converts a transform corrected for the panel orientation
* to its logical (user-visible) transform.
*/
MetaMonitorTransform meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor,
MetaMonitorTransform transform);
uint32_t meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled);
gboolean meta_monitor_get_suggested_position (MetaMonitor *monitor,

View File

@@ -78,6 +78,7 @@ struct _MetaOutput
CoglSubpixelOrder subpixel_order;
MetaConnectorType connector_type;
MetaMonitorTransform panel_orientation_transform;
MetaCrtcMode *preferred_mode;
MetaCrtcMode **modes;

View File

@@ -51,7 +51,7 @@ common_resolutions = [
output_lines = [
"/* Generated by gen-default-modes.py */\n",
"static const drmModeModeInfo meta_default_drm_mode_infos[] = {",
"static const drmModeModeInfo meta_default_landscape_drm_mode_infos[] = {",
]
def sync_flags(hsync, vsync):
@@ -76,6 +76,21 @@ def drm_mode_info_from_modeline(line):
sync_flags(sline[11], sline[12]),
sline[1])
def portrait_drm_mode_info_from_modeline(line):
sline = line.split()
return "{ %d, %d, %d, %d, %d, 0, %d, %d, %d, %d, 0, 0, %s, DRM_MODE_TYPE_DEFAULT, \"%dx%d_60.00\" }," % \
(int(float(sline[2]) * 1000),
int(sline[7]),
int(sline[8]),
int(sline[9]),
int(sline[10]),
int(sline[3]),
int(sline[4]),
int(sline[5]),
int(sline[6]),
sync_flags(sline[12], sline[11]),
int(sline[7]), int(sline[3]))
for resolution in common_resolutions:
cvt = os.popen("%s %s %s" % ('cvt', resolution[0], resolution[1]))
cvt.readline() # discard comment line
@@ -84,6 +99,16 @@ for resolution in common_resolutions:
cvt.close()
output_lines.append("};")
output_lines.append("")
output_lines.append("static const drmModeModeInfo meta_default_portrait_drm_mode_infos[] = {")
for resolution in common_resolutions:
cvt = os.popen("%s %s %s" % ('cvt', resolution[0], resolution[1]))
cvt.readline() # discard comment line
line = cvt.readline()
output_lines.append(portrait_drm_mode_info_from_modeline(line))
cvt.close()
output_lines.append("};")
for line in output_lines:
sys.stdout.write(line + "\n")
sys.stdout.flush()

View File

@@ -465,6 +465,7 @@ cursor_over_transformed_logical_monitor (MetaCursorRenderer *renderer,
MetaRectangle logical_monitor_layout;
ClutterRect logical_monitor_rect;
MetaMonitorTransform transform;
GList *monitors, *l_mon;
logical_monitor_layout =
meta_logical_monitor_get_layout (logical_monitor);
@@ -475,9 +476,17 @@ cursor_over_transformed_logical_monitor (MetaCursorRenderer *renderer,
NULL))
continue;
transform = meta_logical_monitor_get_transform (logical_monitor);
if (transform != META_MONITOR_TRANSFORM_NORMAL)
return TRUE;
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (l_mon = monitors; l_mon; l_mon = l_mon->next)
{
MetaMonitor *monitor = l_mon->data;
transform = meta_logical_monitor_get_transform (logical_monitor);
/* Get transform corrected for LCD panel-orientation. */
transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
if (transform != META_MONITOR_TRANSFORM_NORMAL)
return TRUE;
}
}
return FALSE;

View File

@@ -1,6 +1,6 @@
/* Generated by gen-default-modes.py */
static const drmModeModeInfo meta_default_drm_mode_infos[] = {
static const drmModeModeInfo meta_default_landscape_drm_mode_infos[] = {
{ 38250, 800, 832, 912, 1024, 0, 600, 603, 607, 624, 0, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC, DRM_MODE_TYPE_DEFAULT, "800x600_60.00" },
{ 63500, 1024, 1072, 1176, 1328, 0, 768, 771, 775, 798, 0, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC, DRM_MODE_TYPE_DEFAULT, "1024x768_60.00" },
{ 81750, 1152, 1216, 1336, 1520, 0, 864, 867, 871, 897, 0, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC, DRM_MODE_TYPE_DEFAULT, "1152x864_60.00" },
@@ -27,3 +27,31 @@ static const drmModeModeInfo meta_default_drm_mode_infos[] = {
{ 813000, 4096, 4440, 4888, 5680, 0, 2304, 2307, 2312, 2386, 0, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC, DRM_MODE_TYPE_DEFAULT, "4096x2304_60.00" },
{ 1276500, 5120, 5560, 6128, 7136, 0, 2880, 2883, 2888, 2982, 0, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC, DRM_MODE_TYPE_DEFAULT, "5120x2880_60.00" },
};
static const drmModeModeInfo meta_default_portrait_drm_mode_infos[] = {
{ 38250, 600, 603, 607, 624, 0, 800, 832, 912, 1024, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "600x800_60.00" },
{ 63500, 768, 771, 775, 798, 0, 1024, 1072, 1176, 1328, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "768x1024_60.00" },
{ 81750, 864, 867, 871, 897, 0, 1152, 1216, 1336, 1520, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "864x1152_60.00" },
{ 101250, 960, 963, 967, 996, 0, 1280, 1360, 1488, 1696, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "960x1280_60.00" },
{ 121750, 1050, 1053, 1057, 1089, 0, 1400, 1488, 1632, 1864, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1050x1400_60.00" },
{ 129000, 1080, 1083, 1087, 1120, 0, 1440, 1528, 1680, 1920, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1080x1440_60.00" },
{ 161000, 1200, 1203, 1207, 1245, 0, 1600, 1712, 1880, 2160, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1200x1600_60.00" },
{ 233500, 1440, 1443, 1447, 1493, 0, 1920, 2064, 2264, 2608, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1440x1920_60.00" },
{ 267250, 1536, 1539, 1543, 1592, 0, 2048, 2208, 2424, 2800, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1536x2048_60.00" },
{ 83500, 800, 803, 809, 831, 0, 1280, 1352, 1480, 1680, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "800x1280_60.00" },
{ 106500, 900, 903, 909, 934, 0, 1440, 1528, 1672, 1904, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "900x1440_60.00" },
{ 146250, 1050, 1053, 1059, 1089, 0, 1680, 1784, 1960, 2240, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1050x1680_60.00" },
{ 193250, 1200, 1203, 1209, 1245, 0, 1920, 2056, 2256, 2592, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1200x1920_60.00" },
{ 348500, 1600, 1603, 1609, 1658, 0, 2560, 2760, 3032, 3504, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1600x2560_60.00" },
{ 74500, 720, 723, 728, 748, 0, 1280, 1344, 1472, 1664, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "720x1280_60.00" },
{ 85250, 768, 771, 781, 798, 0, 1368, 1440, 1576, 1784, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "768x1368_60.00" },
{ 118250, 900, 903, 908, 934, 0, 1600, 1696, 1856, 2112, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "900x1600_60.00" },
{ 173000, 1080, 1083, 1088, 1120, 0, 1920, 2048, 2248, 2576, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1080x1920_60.00" },
{ 197000, 1152, 1155, 1160, 1195, 0, 2048, 2184, 2400, 2752, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1152x2048_60.00" },
{ 312250, 1440, 1443, 1448, 1493, 0, 2560, 2752, 3024, 3488, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1440x2560_60.00" },
{ 396250, 1620, 1623, 1628, 1679, 0, 2880, 3096, 3408, 3936, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1620x2880_60.00" },
{ 492000, 1800, 1803, 1808, 1865, 0, 3200, 3456, 3800, 4400, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "1800x3200_60.00" },
{ 712750, 2160, 2163, 2168, 2237, 0, 3840, 4160, 4576, 5312, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "2160x3840_60.00" },
{ 813000, 2304, 2307, 2312, 2386, 0, 4096, 4440, 4888, 5680, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "2304x4096_60.00" },
{ 1276500, 2880, 2883, 2888, 2982, 0, 5120, 5560, 6128, 7136, 0, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, DRM_MODE_TYPE_DEFAULT, "2880x5120_60.00" },
};

View File

@@ -601,11 +601,21 @@ init_modes (MetaGpuKms *gpu_kms,
g_hash_table_destroy (modes_table);
for (i = 0; i < G_N_ELEMENTS (meta_default_drm_mode_infos); i++)
for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++)
{
MetaCrtcMode *mode;
mode = create_mode (&meta_default_drm_mode_infos[i], (long) mode_id);
mode = create_mode (&meta_default_landscape_drm_mode_infos[i], mode_id);
modes = g_list_append (modes, mode);
mode_id++;
}
for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++)
{
MetaCrtcMode *mode;
mode = create_mode (&meta_default_portrait_drm_mode_infos[i], mode_id);
modes = g_list_append (modes, mode);
mode_id++;

View File

@@ -229,9 +229,37 @@ meta_output_kms_read_edid (MetaOutput *output)
}
static void
find_connector_properties (MetaGpuKms *gpu_kms,
MetaOutputKms *output_kms)
handle_panel_orientation (MetaOutput *output,
drmModePropertyPtr prop,
int orientation)
{
const char *name = prop->enums[orientation].name;
if (strcmp (name, "Upside Down") == 0)
{
output->panel_orientation_transform = META_MONITOR_TRANSFORM_180;
}
else if (strcmp (name, "Left Side Up") == 0)
{
/* Left side up, rotate 90 degrees counter clockwise to correct */
output->panel_orientation_transform = META_MONITOR_TRANSFORM_90;
}
else if (strcmp (name, "Right Side Up") == 0)
{
/* Right side up, rotate 270 degrees counter clockwise to correct */
output->panel_orientation_transform = META_MONITOR_TRANSFORM_270;
}
else
{
output->panel_orientation_transform = META_MONITOR_TRANSFORM_NORMAL;
}
}
static void
find_connector_properties (MetaGpuKms *gpu_kms,
MetaOutput *output)
{
MetaOutputKms *output_kms = output->driver_private;
drmModeConnector *connector = output_kms->connector;
int fd;
int i;
@@ -268,6 +296,10 @@ find_connector_properties (MetaGpuKms *gpu_kms,
output_kms->hotplug_mode_update = connector->prop_values[i];
else if (strcmp (prop->name, "scaling mode") == 0)
output_kms->has_scaling = TRUE;
else if ((prop->flags & DRM_MODE_PROP_ENUM) &&
strcmp (prop->name, "panel orientation") == 0)
handle_panel_orientation (output, prop,
output_kms->connector->prop_values[i]);
drmModeFreeProperty (prop);
}
@@ -325,7 +357,10 @@ static void
add_common_modes (MetaOutput *output,
MetaGpuKms *gpu_kms)
{
const drmModeModeInfo *drm_mode;
MetaCrtcMode *crtc_mode;
GPtrArray *array;
float refresh_rate;
unsigned i;
unsigned max_hdisplay = 0;
unsigned max_vdisplay = 0;
@@ -333,9 +368,6 @@ add_common_modes (MetaOutput *output,
for (i = 0; i < output->n_modes; i++)
{
const drmModeModeInfo *drm_mode;
float refresh_rate;
drm_mode = output->modes[i]->driver_private;
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
max_hdisplay = MAX (max_hdisplay, drm_mode->hdisplay);
@@ -347,22 +379,37 @@ add_common_modes (MetaOutput *output,
max_refresh_rate *= (1 + SYNC_TOLERANCE);
array = g_ptr_array_new ();
for (i = 0; i < G_N_ELEMENTS (meta_default_drm_mode_infos); i++)
if (max_hdisplay > max_vdisplay)
{
const drmModeModeInfo *drm_mode;
float refresh_rate;
MetaCrtcMode *crtc_mode;
for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++)
{
drm_mode = &meta_default_landscape_drm_mode_infos[i];
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
if (drm_mode->hdisplay > max_hdisplay ||
drm_mode->vdisplay > max_vdisplay ||
refresh_rate > max_refresh_rate)
continue;
drm_mode = &meta_default_drm_mode_infos[i];
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
if (drm_mode->hdisplay > max_hdisplay ||
drm_mode->vdisplay > max_vdisplay ||
refresh_rate > max_refresh_rate)
continue;
crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms,
drm_mode);
g_ptr_array_add (array, crtc_mode);
}
}
else
{
for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++)
{
drm_mode = &meta_default_portrait_drm_mode_infos[i];
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
if (drm_mode->hdisplay > max_hdisplay ||
drm_mode->vdisplay > max_vdisplay ||
refresh_rate > max_refresh_rate)
continue;
crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms,
drm_mode);
g_ptr_array_add (array, crtc_mode);
crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms,
drm_mode);
g_ptr_array_add (array, crtc_mode);
}
}
output->modes = g_renew (MetaCrtcMode *, output->modes,
@@ -442,8 +489,6 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
output->gpu = gpu;
output->winsys_id = connector->connector_id;
output->name = make_output_name (connector);
output->width_mm = connector->mmWidth;
output->height_mm = connector->mmHeight;
switch (connector->subpixel)
{
@@ -469,7 +514,18 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
}
output_kms->connector = connector;
find_connector_properties (gpu_kms, output_kms);
find_connector_properties (gpu_kms, output);
if (meta_monitor_transform_is_rotated (output->panel_orientation_transform))
{
output->width_mm = connector->mmHeight;
output->height_mm = connector->mmWidth;
}
else
{
output->width_mm = connector->mmWidth;
output->height_mm = connector->mmHeight;
}
init_output_modes (output, gpu_kms);

View File

@@ -2342,8 +2342,12 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
MetaMonitorTransform crtc_transform;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
crtc_transform =
meta_monitor_logical_to_crtc_transform (main_monitor,
logical_monitor->transform);
/*
* Pick any monitor and output and check; all CRTCs of a logical monitor will
@@ -2352,10 +2356,10 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
logical_monitor->transform))
crtc_transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
return logical_monitor->transform;
return crtc_transform;
}
static MetaRendererView *

View File

@@ -604,6 +604,38 @@ output_get_connector_type (MetaOutput *output)
return META_CONNECTOR_TYPE_Unknown;
}
static gint
output_get_panel_orientation_transform (MetaOutput *output)
{
Display *xdisplay = xdisplay_from_output (output);
unsigned long nitems, bytes_after;
Atom atom, actual_type;
int actual_format;
g_autofree unsigned char *buffer = NULL;
g_autofree char *str = NULL;
atom = XInternAtom (xdisplay, "panel orientation", False);
XRRGetOutputProperty (xdisplay, (XID)output->winsys_id, atom,
0, G_MAXLONG, False, False, XA_ATOM,
&actual_type, &actual_format,
&nitems, &bytes_after, &buffer);
if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
return META_MONITOR_TRANSFORM_NORMAL;
str = XGetAtomName (xdisplay, *(Atom *)buffer);
if (strcmp (str, "Upside Down") == 0)
return META_MONITOR_TRANSFORM_180;
if (strcmp (str, "Left Side Up") == 0)
return META_MONITOR_TRANSFORM_90;
if (strcmp (str, "Right Side Up") == 0)
return META_MONITOR_TRANSFORM_270;
return META_MONITOR_TRANSFORM_NORMAL;
}
static void
output_get_tile_info (MetaOutput *output)
{
@@ -737,13 +769,25 @@ meta_create_xrandr_output (MetaGpuXrandr *gpu_xrandr,
meta_output_parse_edid (output, edid);
g_bytes_unref (edid);
output->width_mm = xrandr_output->mm_width;
output->height_mm = xrandr_output->mm_height;
output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
output->hotplug_mode_update = output_get_hotplug_mode_update (output);
output->suggested_x = output_get_suggested_x (output);
output->suggested_y = output_get_suggested_y (output);
output->connector_type = output_get_connector_type (output);
output->panel_orientation_transform =
output_get_panel_orientation_transform (output);
if (meta_monitor_transform_is_rotated (
output->panel_orientation_transform))
{
output->width_mm = xrandr_output->mm_height;
output->height_mm = xrandr_output->mm_width;
}
else
{
output->width_mm = xrandr_output->mm_width;
output->height_mm = xrandr_output->mm_height;
}
output_get_tile_info (output);
output_get_modes (output, xrandr_output);

View File

@@ -50,8 +50,12 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
MetaMonitorTransform crtc_transform;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
crtc_transform =
meta_monitor_logical_to_crtc_transform (main_monitor,
logical_monitor->transform);
/*
* Pick any monitor and output and check; all CRTCs of a logical monitor will
@@ -60,10 +64,10 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
logical_monitor->transform))
crtc_transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
return logical_monitor->transform;
return crtc_transform;
}
static MetaRendererView *

View File

@@ -419,11 +419,13 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp);
meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
{
meta_dnd_wayland_handle_end_modal (compositor);
meta_display_sync_wayland_input_focus (display);
}
#endif
}
static void
@@ -1454,6 +1456,14 @@ meta_compositor_hide_tile_preview (MetaCompositor *compositor)
meta_plugin_manager_hide_tile_preview (compositor->plugin_mgr);
}
void
meta_compositor_show_tile_picker (MetaCompositor *compositor,
MetaWindow *window,
int tile_monitor_number)
{
meta_plugin_manager_show_tile_picker (compositor->plugin_mgr, window, tile_monitor_number);
}
void
meta_compositor_show_window_menu (MetaCompositor *compositor,
MetaWindow *window,

View File

@@ -404,3 +404,24 @@ meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_m
return meta_inhibit_shortcuts_dialog_default_new (window);
}
gboolean
meta_plugin_manager_show_tile_picker (MetaPluginManager *plugin_mgr,
MetaWindow *window,
int tile_monitor_number)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = plugin_mgr->compositor->display;
if (display->display_opening)
return FALSE;
if (klass->show_tile_picker)
{
klass->show_tile_picker (plugin, window, tile_monitor_number);
return TRUE;
}
return FALSE;
}

View File

@@ -98,4 +98,9 @@ MetaInhibitShortcutsDialog *
meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_mgr,
MetaWindow *window);
gboolean meta_plugin_manager_show_tile_picker (MetaPluginManager *plugin_mgr,
MetaWindow *window,
int tile_monitor_number);
#endif

View File

@@ -74,13 +74,6 @@ typedef enum {
*/
#define N_IGNORED_CROSSING_SERIALS 10
typedef enum {
META_TILE_NONE,
META_TILE_LEFT,
META_TILE_RIGHT,
META_TILE_MAXIMIZED
} MetaTileMode;
typedef enum {
/* Normal interaction where you're interacting with windows.
* Events go to windows normally. */

View File

@@ -593,8 +593,6 @@ void meta_window_unmanage (MetaWindow *window,
guint32 timestamp);
void meta_window_queue (MetaWindow *window,
guint queuebits);
void meta_window_tile (MetaWindow *window,
MetaTileMode mode);
void meta_window_restore_tile (MetaWindow *window,
MetaTileMode mode,
int width,
@@ -712,7 +710,6 @@ void meta_window_update_for_monitors_changed (MetaWindow *window);
void meta_window_on_all_workspaces_changed (MetaWindow *window);
gboolean meta_window_should_attach_to_parent (MetaWindow *window);
gboolean meta_window_can_tile_side_by_side (MetaWindow *window);
void meta_window_compute_tile_match (MetaWindow *window);

View File

@@ -179,6 +179,7 @@ enum {
PROP_GTK_APP_MENU_OBJECT_PATH,
PROP_GTK_MENUBAR_OBJECT_PATH,
PROP_ON_ALL_WORKSPACES,
PROP_TILE_MODE,
LAST_PROP,
};
@@ -399,6 +400,9 @@ meta_window_get_property(GObject *object,
case PROP_ON_ALL_WORKSPACES:
g_value_set_boolean (value, win->on_all_workspaces);
break;
case PROP_TILE_MODE:
g_value_set_enum (value, win->tile_mode);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -413,6 +417,9 @@ meta_window_set_property(GObject *object,
{
switch (prop_id)
{
case PROP_TILE_MODE:
meta_window_tile (META_WINDOW (object), g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -588,6 +595,13 @@ meta_window_class_init (MetaWindowClass *klass)
"Whether the window is set to appear on all workspaces",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_props[PROP_TILE_MODE] =
g_param_spec_enum ("tile-mode",
"Tile mode",
"The tile state of the window",
META_TYPE_TILE_MODE,
META_TILE_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROP, obj_props);
@@ -2833,6 +2847,7 @@ meta_window_maximize (MetaWindow *window,
window->maximized_vertically = FALSE;
window->tile_mode = META_TILE_NONE;
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_TILE_MODE]);
}
meta_window_maximize_internal (window,
@@ -3085,19 +3100,30 @@ update_edge_constraints (MetaWindow *window)
}
}
/**
* meta_window_tile:
* @window: a #MetaWindow
* @tile_mode: the new #MetaTileMode
*
* Tiles @window according to @tile_mode.
*/
void
meta_window_tile (MetaWindow *window,
MetaTileMode tile_mode)
{
MetaMaximizeFlags directions;
MetaRectangle old_frame_rect, old_buffer_rect;
gboolean should_notify;
should_notify = window->tile_mode != tile_mode;
meta_window_get_tile_fraction (window, tile_mode, &window->tile_hfraction);
window->tile_mode = tile_mode;
/* Don't do anything if no tiling is requested */
if (window->tile_mode == META_TILE_NONE)
return;
goto out;
if (window->tile_mode == META_TILE_MAXIMIZED)
directions = META_MAXIMIZE_BOTH;
@@ -3126,6 +3152,16 @@ meta_window_tile (MetaWindow *window,
if (window->frame)
meta_frame_queue_draw (window->frame);
/* If the window doesn't have a tile match after being tiled, ask the
* compositor to show the tile picker.
*/
if (META_WINDOW_TILED_SIDE_BY_SIDE (window) && !window->tile_match)
meta_compositor_show_tile_picker (window->display->compositor, window, window->monitor->number);
out:
if (should_notify)
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_TILE_MODE]);
}
void
@@ -3144,6 +3180,15 @@ meta_window_can_tile_maximized (MetaWindow *window)
return window->has_maximize_func;
}
/**
* meta_window_can_tile_side_by_side:
* @window: a #MetaWindow
*
* Retrieves whether @window can be tiled horizontally.
*
* Returns: %TRUE if @window can be tiled horizontally, %FALSE
* otherwise.
*/
gboolean
meta_window_can_tile_side_by_side (MetaWindow *window)
{
@@ -3169,6 +3214,20 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
client_rect.height >= window->size_hints.min_height;
}
/**
* meta_window_get_tile_mode:
* @window: a #MetaWindow
*
* Retrieves the current tile mode of @window.
*
* Returns: a #MetaTileMode enum value
*/
MetaTileMode
meta_window_get_tile_mode (MetaWindow *window)
{
return window->tile_mode;
}
static void
unmaximize_window_before_freeing (MetaWindow *window)
{
@@ -3237,7 +3296,10 @@ meta_window_unmaximize (MetaWindow *window,
meta_window_get_buffer_rect (window, &old_buffer_rect);
if (unmaximize_vertically)
window->tile_mode = META_TILE_NONE;
{
window->tile_mode = META_TILE_NONE;
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_TILE_MODE]);
}
meta_topic (META_DEBUG_WINDOW_OPS,
"Unmaximizing %s%s\n",

View File

@@ -122,6 +122,10 @@ void meta_compositor_show_tile_preview (MetaCompositor *compositor,
MetaRectangle *tile_rect,
int tile_monitor_number);
void meta_compositor_hide_tile_preview (MetaCompositor *compositor);
void meta_compositor_show_tile_picker (MetaCompositor *compositor,
MetaWindow *window,
int tile_monitor_number);
void meta_compositor_show_window_menu (MetaCompositor *compositor,
MetaWindow *window,
MetaWindowMenuType menu,

View File

@@ -251,6 +251,14 @@ struct _MetaPluginClass
*/
MetaInhibitShortcutsDialog * (* create_inhibit_shortcuts_dialog) (MetaPlugin *plugin,
MetaWindow *window);
/**
* MetaPluginClass::show_tile_picker:
*
*/
void * (* show_tile_picker) (MetaPlugin *plugin,
MetaWindow *window,
int tile_monitor_number);
};
/**

View File

@@ -91,6 +91,21 @@ typedef enum {
META_WINDOW_CLIENT_TYPE_X11
} MetaWindowClientType;
/**
* MetaTileMode:
* @META_TILE_NONE: the window is not tiled
* @META_TILE_LEFT: the window is tiled at the left side of the monitor
* @META_TILE_RIGHT: the window is tiled at the right side of the monitor
* @META_TILE_MAXIMIZED: the window is maximized (i.e. both left and right sides)
*/
typedef enum {
META_TILE_NONE,
META_TILE_LEFT,
META_TILE_RIGHT,
META_TILE_MAXIMIZED
} MetaTileMode;
#define META_TYPE_WINDOW (meta_window_get_type ())
#define META_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW, MetaWindow))
#define META_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW, MetaWindowClass))
@@ -260,4 +275,10 @@ gboolean meta_window_is_client_decorated (MetaWindow *window);
gboolean meta_window_titlebar_is_onscreen (MetaWindow *window);
void meta_window_shove_titlebar_onscreen (MetaWindow *window);
gboolean meta_window_can_tile_side_by_side (MetaWindow *window);
MetaTileMode meta_window_get_tile_mode (MetaWindow *window);
void meta_window_tile (MetaWindow *window,
MetaTileMode mode);
#endif

View File

@@ -112,6 +112,7 @@ typedef struct _MonitorTestCaseOutput
gboolean is_laptop_panel;
gboolean is_underscanning;
const char *serial;
MetaMonitorTransform panel_orientation_transform;
} MonitorTestCaseOutput;
typedef struct _MonitorTestCaseCrtc
@@ -1009,6 +1010,8 @@ create_monitor_test_setup (MonitorTestCase *test_case,
: META_CONNECTOR_TYPE_DisplayPort);
output->tile_info = test_case->setup.outputs[i].tile_info;
output->is_underscanning = test_case->setup.outputs[i].is_underscanning;
output->panel_orientation_transform =
test_case->setup.outputs[i].panel_orientation_transform;
output->driver_private = output_test;
output->driver_notify = (GDestroyNotify) meta_output_test_destroy_notify;
@@ -3090,6 +3093,39 @@ meta_test_monitor_preferred_non_first_mode (void)
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_non_upright_panel (void)
{
MonitorTestCase test_case = initial_test_case;
MetaMonitorTestSetup *test_setup;
test_case.setup.modes[1] = (MonitorTestCaseMode) {
.width = 768,
.height = 1024,
.refresh_rate = 60.0,
};
test_case.setup.n_modes = 2;
test_case.setup.outputs[0].modes[0] = 1;
test_case.setup.outputs[0].preferred_mode = 1;
test_case.setup.outputs[0].panel_orientation_transform =
META_MONITOR_TRANSFORM_90;
/*
* Note we do not swap outputs[0].width_mm and height_mm, because these get
* swapped for rotated panels inside the xrandr / kms code and we directly
* create a dummy output here, skipping this code.
*/
test_case.setup.crtcs[0].current_mode = 1;
test_case.expect.monitors[0].modes[0].crtc_modes[0].crtc_mode = 1;
test_case.expect.crtcs[0].current_mode = 1;
test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_90;
test_setup = create_monitor_test_setup (&test_case,
MONITOR_TEST_FLAG_NO_STORED);
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_custom_vertical_config (void)
{
@@ -5884,6 +5920,8 @@ init_monitor_tests (void)
meta_test_monitor_underscanning_config);
add_monitor_test ("/backends/monitor/preferred-non-first-mode",
meta_test_monitor_preferred_non_first_mode);
add_monitor_test ("/backends/monitor/non-upright-panel",
meta_test_monitor_non_upright_panel);
add_monitor_test ("/backends/monitor/custom/vertical-config",
meta_test_monitor_custom_vertical_config);