Giter Site home page Giter Site logo

kylegospo / gnome-vrr Goto Github PK

View Code? Open in Web Editor NEW
24.0 3.0 10.0 256 KB

Fedora spec files for Mutter & GNOME Control Center with Dor Askayo's Wayland VRR MR applied.

Home Page: https://copr.fedorainfracloud.org/coprs/kylegospo/gnome-vrr/

License: GNU General Public License v2.0

Shell 100.00%
copr fedora gnome gnome-shell vrr wayland

gnome-vrr's Introduction

gnome-vrr

Fedora spec files for Mutter & GNOME Control Center with Dor Askayo's Wayland VRR MR applied.

Mutter

Build Status

GNOME Control Center

Build Status

Releases

You can get releases for Fedora from my Copr.

gnome-vrr's People

Contributors

kylegospo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gnome-vrr's Issues

Issue installing on brand new fedora 38 silverblue

Resolving dependencies... done
Applying 4 overrides and 222 overlays
Processing packages... done
error: Checkout mutter-44.3.vrr.16-1.fc38.x86_64: Hardlinking 10/8ac100da7d75b7c4b74b8a0a3609b1ff8fadc82e66ff045aa652c749b9b9c1.file to org.gnome.mutter.gschema.xml: File exists
Have never had this issue while staging many hosts with the vrr patch, this particular hardware included. Any help would be appreciated!

Updated for 45.5?

Is there going to be a build for 45.5 until Fedora 40 releases with official support? I was using this (working great) on 45.4 but with a fresh install I can't download these packages as they're older than what I'm using.

Thanks.

After installation, I can't switch to wayland

I use Wayland on Fedora 38, AMD RX6600

Installing:
mutter 44.3.vrr.15-1
gnome-control-center 44.3.vrr.4-1
xorg-x11-server-Xwayland 23.1.2-1

And wayland is forcibly replaced by Xorg. How to solve it?

Code rebase causing issue on fresh install

The following shows up when I try imaging a brand new Fedora 39 PC with the VRR copr:

error: No matches for 'xorg-x11-server-Xwayland' in repo 'copr:copr.fedorainfracloud.org:kylegospo:gnome-vrr'

I have replicated this on multiple systems at this point.

43.3: XWayland apps steal focus

XWayland apps steal focus Since 43.3. That makes working with other windows really hard as soon as an XWayland window has gotten the focus.

Upstream Bug
https://gitlab.gnome.org/GNOME/mutter/-/issues/2654

The upstream Fedora package includes a hotfix patch for this (0001-x11-Avoid-updating-focus-on-wayland-compositor.patch in https://kojipkgs.fedoraproject.org//packages/mutter/43.3/2.fc37/src/mutter-43.3-2.fc37.src.rpm) from the MR https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2841.

Could you also include this patch?

Please update to 44.3 and include some fixes

Hi there

Could you please considier upgrading to 44.3 and include some additional fixes ?
I tried it myself but somehow the vrr toggle wont appear.

I tryed to alter your files but it appears I didnt have any success.

heres the patch
diff --git a/gnome-control-center/gnome-control-center.spec b/gnome-control-center/gnome-control-center.spec
index 1c37369..78ba902 100644
--- a/gnome-control-center/gnome-control-center.spec
+++ b/gnome-control-center/gnome-control-center.spec
@@ -10,11 +10,11 @@
 %define nm_version 1.24
 
 %global gnome_major_version 44
-%global gnome_version %{gnome_major_version}.2
+%global gnome_version %{gnome_major_version}.3
 %global tarball_version %%(echo %{gnome_version} | tr '~' '.')
 
 Name:           gnome-control-center
-Version:        %{gnome_version}.vrr.4
+Version:        %{gnome_version}.vrr.1
 Release:        %autorelease
 Summary:        Utilities to configure the GNOME desktop
 
diff --git a/mutter/3085.patch b/mutter/3085.patch
index 08e3c3f..1af1bc6 100644
--- a/mutter/3085.patch
+++ b/mutter/3085.patch
@@ -1,19 +1,21 @@
-From b30a051cd190f06f0236339a5e24a391ce6f12ee Mon Sep 17 00:00:00 2001
-From: GloriousEggroll <[email protected]>
-Date: Fri, 23 Jun 2023 10:26:17 -0600
-Subject: [PATCH 2/3] 3085
+From d67d22f948a1b43e626b85db007e1410bb906d28 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20=C3=85dahl?= <[email protected]>
+Date: Thu, 22 Jun 2023 10:35:27 +0200
+Subject: [PATCH] backend: Init settings before initable_init
 
+This means the settings instance is there before the backend backend's
+initable_init() function gets called.
+
+Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3085>
 ---
- src/backends/meta-backend.c      |    3 +-
- src/backends/meta-backend.c.orig | 1744 ++++++++++++++++++++++++++++++
- 2 files changed, 1746 insertions(+), 1 deletion(-)
- create mode 100644 src/backends/meta-backend.c.orig
+ src/backends/meta-backend.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
-index e77b961..7e64c4f 100644
+index 1b864f3606..0a2ff8bb99 100644
 --- a/src/backends/meta-backend.c
 +++ b/src/backends/meta-backend.c
-@@ -787,6 +787,8 @@ meta_backend_constructed (GObject *object)
+@@ -791,6 +791,8 @@ meta_backend_constructed (GObject *object)
  
    g_assert (priv->context);
  
@@ -22,7 +24,7 @@ index e77b961..7e64c4f 100644
  #ifdef HAVE_LIBWACOM
    priv->wacom_db = libwacom_database_new ();
    if (!priv->wacom_db)
-@@ -1181,7 +1183,6 @@ meta_backend_initable_init (GInitable     *initable,
+@@ -1201,7 +1203,6 @@ meta_backend_initable_init (GInitable     *initable,
    MetaBackend *backend = META_BACKEND (initable);
    MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
  
@@ -30,1756 +32,6 @@ index e77b961..7e64c4f 100644
    priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL);
  
    priv->monitor_manager = meta_backend_create_monitor_manager (backend, error);
-diff --git a/src/backends/meta-backend.c.orig b/src/backends/meta-backend.c.orig
-new file mode 100644
-index 0000000..e77b961
---- /dev/null
-+++ b/src/backends/meta-backend.c.orig
-@@ -0,0 +1,1744 @@
-+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-+
-+/*
-+ * Copyright (C) 2014 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:
-+ *     Jasper St. Pierre <[email protected]>
-+ */
-+
-+/**
-+ * SECTION:meta-backend
-+ * @title: MetaBackend
-+ * @short_description: Handles monitor config, modesetting, cursor sprites, ...
-+ *
-+ * MetaBackend is the abstraction that deals with several things like:
-+ * - Modesetting (depending on the backend, this can be done either by X or KMS)
-+ * - Initializing the #MetaSettings
-+ * - Setting up Monitor configuration
-+ * - Input device configuration (using the #ClutterDeviceManager)
-+ * - Creating the #MetaRenderer
-+ * - Setting up the stage of the scene graph (using #MetaStage)
-+ * - Creating the object that deals with the cursor (using #MetaCursorTracker)
-+ *     and its possible pointer constraint (using #MetaPointerConstraint)
-+ * - Setting the cursor sprite (using #MetaCursorRenderer)
-+ * - Interacting with logind (using the appropriate D-Bus interface)
-+ * - Querying UPower (over D-Bus) to know when the lid is closed
-+ * - Setup Remote Desktop / Screencasting (#MetaRemoteDesktop)
-+ * - Setup the #MetaEgl object
-+ *
-+ * Note that the #MetaBackend is not a subclass of #ClutterBackend. It is
-+ * responsible for creating the correct one, based on the backend that is
-+ * used (#MetaBackendNative or #MetaBackendX11).
-+ */
-+
-+#include "config.h"
-+
-+#include "backends/meta-backend-private.h"
-+
-+#include <stdlib.h>
-+
-+#include "backends/meta-barrier-private.h"
-+#include "backends/meta-cursor-renderer.h"
-+#include "backends/meta-cursor-tracker-private.h"
-+#include "backends/meta-dbus-session-watcher.h"
-+#include "backends/meta-idle-manager.h"
-+#include "backends/meta-idle-monitor-private.h"
-+#include "backends/meta-input-mapper-private.h"
-+#include "backends/meta-input-settings-private.h"
-+#include "backends/meta-logical-monitor.h"
-+#include "backends/meta-monitor-manager-dummy.h"
-+#include "backends/meta-remote-access-controller-private.h"
-+#include "backends/meta-settings-private.h"
-+#include "backends/meta-stage-private.h"
-+#include "backends/x11/meta-backend-x11.h"
-+#include "clutter/clutter-mutter.h"
-+#include "clutter/clutter-seat-private.h"
-+#include "compositor/meta-dnd-private.h"
-+#include "core/meta-context-private.h"
-+#include "meta/main.h"
-+#include "meta/meta-backend.h"
-+#include "meta/meta-context.h"
-+#include "meta/meta-enum-types.h"
-+#include "meta/util.h"
-+
-+#ifdef HAVE_REMOTE_DESKTOP
-+#include "backends/meta-remote-desktop.h"
-+#include "backends/meta-screen-cast.h"
-+#endif
-+
-+#ifdef HAVE_NATIVE_BACKEND
-+#include "backends/native/meta-backend-native.h"
-+#endif
-+
-+#ifdef HAVE_WAYLAND
-+#include "wayland/meta-wayland.h"
-+#endif
-+
-+enum
-+{
-+  PROP_0,
-+
-+  PROP_CONTEXT,
-+  PROP_CAPABILITIES,
-+
-+  N_PROPS
-+};
-+
-+static GParamSpec *obj_props[N_PROPS];
-+
-+enum
-+{
-+  KEYMAP_CHANGED,
-+  KEYMAP_LAYOUT_GROUP_CHANGED,
-+  LAST_DEVICE_CHANGED,
-+  LID_IS_CLOSED_CHANGED,
-+  GPU_ADDED,
-+  PREPARE_SHUTDOWN,
-+
-+  N_SIGNALS
-+};
-+
-+static guint signals[N_SIGNALS];
-+
-+#define HIDDEN_POINTER_TIMEOUT 300 /* ms */
-+
-+struct _MetaBackendPrivate
-+{
-+  MetaContext *context;
-+
-+  MetaMonitorManager *monitor_manager;
-+  MetaOrientationManager *orientation_manager;
-+  MetaCursorTracker *cursor_tracker;
-+  MetaInputMapper *input_mapper;
-+  MetaIdleManager *idle_manager;
-+  MetaRenderer *renderer;
-+  MetaColorManager *color_manager;
-+#ifdef HAVE_EGL
-+  MetaEgl *egl;
-+#endif
-+  MetaSettings *settings;
-+  MetaDbusSessionWatcher *dbus_session_watcher;
-+  MetaRemoteAccessController *remote_access_controller;
-+#ifdef HAVE_REMOTE_DESKTOP
-+  MetaScreenCast *screen_cast;
-+  MetaRemoteDesktop *remote_desktop;
-+#endif
-+
-+#ifdef HAVE_LIBWACOM
-+  WacomDeviceDatabase *wacom_db;
-+#endif
-+#ifdef HAVE_GNOME_DESKTOP
-+  GnomePnpIds *pnp_ids;
-+#endif
-+
-+  ClutterContext *clutter_context;
-+  ClutterSeat *default_seat;
-+  ClutterActor *stage;
-+
-+  GList *gpus;
-+  GList *hw_cursor_inhibitors;
-+
-+  gboolean is_pointer_position_initialized;
-+
-+  guint device_update_idle_id;
-+
-+  ClutterInputDevice *current_device;
-+
-+  MetaPointerConstraint *client_pointer_constraint;
-+  MetaDnd *dnd;
-+
-+  guint upower_watch_id;
-+  GDBusProxy *upower_proxy;
-+  gboolean lid_is_closed;
-+  gboolean on_battery;
-+
-+  guint sleep_signal_id;
-+  GCancellable *cancellable;
-+  GDBusConnection *system_bus;
-+
-+  uint32_t last_pointer_motion;
-+};
-+typedef struct _MetaBackendPrivate MetaBackendPrivate;
-+
-+typedef struct _MetaBackendSource MetaBackendSource;
-+
-+struct _MetaBackendSource
-+{
-+  GSource parent;
-+  MetaBackend *backend;
-+};
-+
-+static void
-+initable_iface_init (GInitableIface *initable_iface);
-+
-+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaBackend, meta_backend, G_TYPE_OBJECT,
-+                                  G_ADD_PRIVATE (MetaBackend)
-+                                  G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-+                                                         initable_iface_init));
-+
-+static void
-+meta_backend_dispose (GObject *object)
-+{
-+  MetaBackend *backend = META_BACKEND (object);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  g_clear_pointer (&priv->cursor_tracker, meta_cursor_tracker_destroy);
-+  g_clear_object (&priv->current_device);
-+  g_clear_object (&priv->color_manager);
-+  g_clear_object (&priv->monitor_manager);
-+  g_clear_object (&priv->orientation_manager);
-+#ifdef HAVE_REMOTE_DESKTOP
-+  g_clear_object (&priv->remote_desktop);
-+  g_clear_object (&priv->screen_cast);
-+#endif
-+  g_clear_object (&priv->dbus_session_watcher);
-+  g_clear_object (&priv->remote_access_controller);
-+
-+#ifdef HAVE_LIBWACOM
-+  g_clear_pointer (&priv->wacom_db, libwacom_database_destroy);
-+#endif
-+#ifdef HAVE_GNOME_DESKTOP
-+  g_clear_object (&priv->pnp_ids);
-+#endif
-+
-+  if (priv->sleep_signal_id)
-+    {
-+      g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
-+      priv->sleep_signal_id = 0;
-+    }
-+
-+  if (priv->upower_watch_id)
-+    {
-+      g_bus_unwatch_name (priv->upower_watch_id);
-+      priv->upower_watch_id = 0;
-+    }
-+
-+  g_cancellable_cancel (priv->cancellable);
-+  g_clear_object (&priv->cancellable);
-+  g_clear_object (&priv->system_bus);
-+  g_clear_object (&priv->upower_proxy);
-+
-+  g_clear_handle_id (&priv->device_update_idle_id, g_source_remove);
-+
-+  g_clear_object (&priv->settings);
-+
-+  g_clear_pointer (&priv->default_seat, clutter_seat_destroy);
-+  g_clear_pointer (&priv->stage, clutter_actor_destroy);
-+  g_clear_pointer (&priv->idle_manager, meta_idle_manager_free);
-+  g_clear_object (&priv->renderer);
-+  g_clear_pointer (&priv->clutter_context, clutter_context_free);
-+  g_clear_list (&priv->gpus, g_object_unref);
-+
-+  G_OBJECT_CLASS (meta_backend_parent_class)->dispose (object);
-+}
-+
-+void
-+meta_backend_destroy (MetaBackend *backend)
-+{
-+  g_object_run_dispose (G_OBJECT (backend));
-+  g_object_unref (backend);
-+}
-+
-+static void
-+meta_backend_sync_screen_size (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  int width, height;
-+
-+  meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height);
-+
-+  META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
-+}
-+
-+static void
-+reset_pointer_position (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  MetaMonitorManager *monitor_manager = priv->monitor_manager;
-+  ClutterSeat *seat = priv->default_seat;
-+  MetaLogicalMonitor *primary;
-+
-+  primary =
-+    meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
-+
-+  /* Move the pointer out of the way to avoid hovering over reactive
-+   * elements (e.g. users list at login) causing undesired behaviour. */
-+  clutter_seat_warp_pointer (seat,
-+                             primary->rect.x + primary->rect.width * 0.9,
-+                             primary->rect.y + primary->rect.height * 0.9);
-+}
-+
-+static gboolean
-+should_have_cursor_renderer (ClutterInputDevice *device)
-+{
-+  switch (clutter_input_device_get_device_type (device))
-+    {
-+    case CLUTTER_POINTER_DEVICE:
-+      if (clutter_input_device_get_device_mode (device) ==
-+          CLUTTER_INPUT_MODE_LOGICAL)
-+        return TRUE;
-+
-+      return FALSE;
-+    case CLUTTER_TABLET_DEVICE:
-+      return TRUE;
-+    default:
-+      return FALSE;
-+    }
-+}
-+
-+static void
-+update_cursors (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  ClutterSeat *seat = priv->default_seat;
-+  MetaCursorRenderer *cursor_renderer;
-+  ClutterInputDevice *pointer, *device;
-+  GList *devices, *l;
-+
-+  pointer = clutter_seat_get_pointer (seat);
-+  devices = clutter_seat_list_devices (seat);
-+  devices = g_list_prepend (devices, pointer);
-+
-+  for (l = devices; l; l = l->next)
-+    {
-+      device = l->data;
-+
-+      if (!should_have_cursor_renderer (device))
-+        continue;
-+
-+      cursor_renderer = meta_backend_get_cursor_renderer_for_device (backend,
-+                                                                     device);
-+      if (cursor_renderer)
-+        meta_cursor_renderer_force_update (cursor_renderer);
-+    }
-+
-+  g_list_free (devices);
-+}
-+
-+void
-+meta_backend_monitors_changed (MetaBackend *backend)
-+{
-+  meta_backend_sync_screen_size (backend);
-+  update_cursors (backend);
-+}
-+
-+static gboolean
-+update_last_device (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  priv->device_update_idle_id = 0;
-+  g_signal_emit (backend, signals[LAST_DEVICE_CHANGED], 0,
-+                 priv->current_device);
-+
-+  return G_SOURCE_REMOVE;
-+}
-+
-+static void
-+meta_backend_update_last_device (MetaBackend        *backend,
-+                                 ClutterInputDevice *device)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  if (priv->current_device == device)
-+    return;
-+
-+  if (!device ||
-+      clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_LOGICAL)
-+    return;
-+
-+  g_set_object (&priv->current_device, device);
-+
-+  if (priv->device_update_idle_id == 0)
-+    {
-+      priv->device_update_idle_id =
-+        g_idle_add ((GSourceFunc) update_last_device, backend);
-+      g_source_set_name_by_id (priv->device_update_idle_id,
-+                               "[mutter] update_last_device");
-+    }
-+}
-+
-+static inline gboolean
-+determine_hotplug_pointer_visibility (ClutterSeat *seat)
-+{
-+  g_autoptr (GList) devices = NULL;
-+  const GList *l;
-+  gboolean has_touchscreen = FALSE, has_pointer = FALSE, has_tablet = FALSE;
-+
-+  devices = clutter_seat_list_devices (seat);
-+
-+  for (l = devices; l; l = l->next)
-+    {
-+      ClutterInputDevice *device = l->data;
-+      ClutterInputDeviceType device_type;
-+
-+      device_type = clutter_input_device_get_device_type (device);
-+
-+      if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
-+        has_touchscreen = TRUE;
-+      if (device_type == CLUTTER_POINTER_DEVICE ||
-+          device_type == CLUTTER_TOUCHPAD_DEVICE)
-+        has_pointer = TRUE;
-+      if (device_type == CLUTTER_TABLET_DEVICE ||
-+          device_type == CLUTTER_PEN_DEVICE ||
-+          device_type == CLUTTER_ERASER_DEVICE)
-+        {
-+          if (meta_is_wayland_compositor ())
-+            has_tablet = TRUE;
-+          else
-+            has_pointer = TRUE;
-+        }
-+    }
-+
-+  return has_pointer && !has_touchscreen && !has_tablet;
-+}
-+
-+static void
-+on_device_added (ClutterSeat        *seat,
-+                 ClutterInputDevice *device,
-+                 gpointer            user_data)
-+{
-+  MetaBackend *backend = META_BACKEND (user_data);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  ClutterInputDeviceType device_type;
-+
-+  if (clutter_input_device_get_device_mode (device) ==
-+      CLUTTER_INPUT_MODE_LOGICAL)
-+    return;
-+
-+  device_type = clutter_input_device_get_device_type (device);
-+
-+  if (device_type == CLUTTER_TOUCHSCREEN_DEVICE ||
-+      device_type == CLUTTER_POINTER_DEVICE)
-+    {
-+      meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker,
-+                                               determine_hotplug_pointer_visibility (seat));
-+    }
-+
-+  if (device_type == CLUTTER_TOUCHSCREEN_DEVICE ||
-+      device_type == CLUTTER_TABLET_DEVICE ||
-+      device_type == CLUTTER_PEN_DEVICE ||
-+      device_type == CLUTTER_ERASER_DEVICE ||
-+      device_type == CLUTTER_CURSOR_DEVICE ||
-+      device_type == CLUTTER_PAD_DEVICE)
-+    meta_input_mapper_add_device (priv->input_mapper, device);
-+}
-+
-+static void
-+on_device_removed (ClutterSeat        *seat,
-+                   ClutterInputDevice *device,
-+                   gpointer            user_data)
-+{
-+  MetaBackend *backend = META_BACKEND (user_data);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  if (clutter_input_device_get_device_mode (device) ==
-+      CLUTTER_INPUT_MODE_LOGICAL)
-+    return;
-+
-+  meta_input_mapper_remove_device (priv->input_mapper, device);
-+
-+  /* If the device the user last interacted goes away, check again pointer
-+   * visibility.
-+   */
-+  if (priv->current_device == device)
-+    {
-+      MetaCursorTracker *cursor_tracker = priv->cursor_tracker;
-+
-+      g_clear_object (&priv->current_device);
-+      g_clear_handle_id (&priv->device_update_idle_id, g_source_remove);
-+
-+      meta_cursor_tracker_set_pointer_visible (cursor_tracker,
-+                                               determine_hotplug_pointer_visibility (seat));
-+    }
-+
-+  if (priv->current_device == device)
-+    meta_backend_update_last_device (backend, NULL);
-+}
-+
-+static void
-+input_mapper_device_mapped_cb (MetaInputMapper    *mapper,
-+                               ClutterInputDevice *device,
-+                               float               matrix[6],
-+                               MetaInputSettings  *input_settings)
-+{
-+  meta_input_settings_set_device_matrix (input_settings, device, matrix);
-+}
-+
-+static void
-+input_mapper_device_enabled_cb (MetaInputMapper    *mapper,
-+                                ClutterInputDevice *device,
-+                                gboolean            enabled,
-+                                MetaInputSettings  *input_settings)
-+{
-+  meta_input_settings_set_device_enabled (input_settings, device, enabled);
-+}
-+
-+static void
-+input_mapper_device_aspect_ratio_cb (MetaInputMapper    *mapper,
-+                                     ClutterInputDevice *device,
-+                                     double              aspect_ratio,
-+                                     MetaInputSettings  *input_settings)
-+{
-+  meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio);
-+}
-+
-+static void
-+on_prepare_shutdown (MetaContext *context,
-+                     MetaBackend *backend)
-+{
-+  g_signal_emit (backend, signals[PREPARE_SHUTDOWN], 0);
-+}
-+
-+static void
-+on_started (MetaContext *context,
-+            MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  ClutterSeat *seat = priv->default_seat;
-+
-+  meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker,
-+                                           determine_hotplug_pointer_visibility (seat));
-+}
-+
-+static void
-+meta_backend_real_post_init (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  ClutterSeat *seat = priv->default_seat;
-+  MetaInputSettings *input_settings;
-+
-+  priv->stage = meta_stage_new (backend);
-+  clutter_actor_realize (priv->stage);
-+  META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
-+
-+  meta_monitor_manager_setup (priv->monitor_manager);
-+
-+  meta_backend_sync_screen_size (backend);
-+
-+  priv->idle_manager = meta_idle_manager_new (backend);
-+
-+  g_signal_connect_object (seat, "device-added",
-+                           G_CALLBACK (on_device_added), backend, 0);
-+  g_signal_connect_object (seat, "device-removed",
-+                           G_CALLBACK (on_device_removed), backend,
-+                           G_CONNECT_AFTER);
-+
-+  priv->input_mapper = meta_input_mapper_new (backend);
-+
-+  input_settings = meta_backend_get_input_settings (backend);
-+
-+  if (input_settings)
-+    {
-+      g_signal_connect (priv->input_mapper, "device-mapped",
-+                        G_CALLBACK (input_mapper_device_mapped_cb),
-+                        input_settings);
-+      g_signal_connect (priv->input_mapper, "device-enabled",
-+                        G_CALLBACK (input_mapper_device_enabled_cb),
-+                        input_settings);
-+      g_signal_connect (priv->input_mapper, "device-aspect-ratio",
-+                        G_CALLBACK (input_mapper_device_aspect_ratio_cb),
-+                        input_settings);
-+    }
-+
-+  priv->remote_access_controller =
-+    meta_remote_access_controller_new ();
-+  priv->dbus_session_watcher =
-+    g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
-+
-+#ifdef HAVE_REMOTE_DESKTOP
-+  priv->screen_cast = meta_screen_cast_new (backend);
-+  meta_remote_access_controller_add (
-+    priv->remote_access_controller,
-+    META_DBUS_SESSION_MANAGER (priv->screen_cast));
-+  priv->remote_desktop = meta_remote_desktop_new (backend);
-+  meta_remote_access_controller_add (
-+    priv->remote_access_controller,
-+    META_DBUS_SESSION_MANAGER (priv->remote_desktop));
-+#endif /* HAVE_REMOTE_DESKTOP */
-+
-+  if (!meta_monitor_manager_is_headless (priv->monitor_manager))
-+    {
-+      reset_pointer_position (backend);
-+      priv->is_pointer_position_initialized = TRUE;
-+    }
-+
-+  meta_monitor_manager_post_init (priv->monitor_manager);
-+
-+  g_signal_connect (priv->context, "prepare-shutdown",
-+                    G_CALLBACK (on_prepare_shutdown), backend);
-+  g_signal_connect (priv->context, "started",
-+                    G_CALLBACK (on_started), backend);
-+}
-+
-+static gboolean
-+meta_backend_real_grab_device (MetaBackend *backend,
-+                               int          device_id,
-+                               uint32_t     timestamp)
-+{
-+  /* Do nothing */
-+  return TRUE;
-+}
-+
-+static gboolean
-+meta_backend_real_ungrab_device (MetaBackend *backend,
-+                                 int          device_id,
-+                                 uint32_t     timestamp)
-+{
-+  /* Do nothing */
-+  return TRUE;
-+}
-+
-+static void
-+meta_backend_real_select_stage_events (MetaBackend *backend)
-+{
-+  /* Do nothing */
-+}
-+
-+static gboolean
-+meta_backend_real_is_lid_closed (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->lid_is_closed;
-+}
-+
-+static MetaCursorTracker *
-+meta_backend_real_create_cursor_tracker (MetaBackend *backend)
-+{
-+  return g_object_new (META_TYPE_CURSOR_TRACKER,
-+                       "backend", backend,
-+                       NULL);
-+}
-+
-+static gboolean
-+meta_backend_real_is_headless (MetaBackend *backend)
-+{
-+  return FALSE;
-+}
-+
-+gboolean
-+meta_backend_is_lid_closed (MetaBackend *backend)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->is_lid_closed (backend);
-+}
-+
-+gboolean
-+meta_backend_is_headless (MetaBackend *backend)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->is_headless (backend);
-+}
-+
-+static void
-+upower_properties_changed (GDBusProxy *proxy,
-+                           GVariant   *changed_properties,
-+                           GStrv       invalidated_properties,
-+                           gpointer    user_data)
-+{
-+  MetaBackend *backend = user_data;
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  GVariant *v;
-+  gboolean reset_idle_time = FALSE;
-+
-+  v = g_variant_lookup_value (changed_properties,
-+                              "LidIsClosed",
-+                              G_VARIANT_TYPE_BOOLEAN);
-+  if (v)
-+    {
-+      gboolean lid_is_closed;
-+
-+      lid_is_closed = g_variant_get_boolean (v);
-+      g_variant_unref (v);
-+
-+      if (lid_is_closed != priv->lid_is_closed)
-+        {
-+          priv->lid_is_closed = lid_is_closed;
-+          g_signal_emit (backend, signals[LID_IS_CLOSED_CHANGED], 0,
-+                         priv->lid_is_closed);
-+
-+          if (!lid_is_closed)
-+            reset_idle_time = TRUE;
-+        }
-+    }
-+
-+  v = g_variant_lookup_value (changed_properties,
-+                              "OnBattery",
-+                              G_VARIANT_TYPE_BOOLEAN);
-+  if (v)
-+    {
-+      gboolean on_battery;
-+
-+      on_battery = g_variant_get_boolean (v);
-+      g_variant_unref (v);
-+
-+      if (on_battery != priv->on_battery)
-+        {
-+          priv->on_battery = on_battery;
-+          reset_idle_time = TRUE;
-+        }
-+    }
-+
-+  if (reset_idle_time)
-+    meta_idle_manager_reset_idle_time (priv->idle_manager);
-+}
-+
-+static void
-+upower_ready_cb (GObject      *source_object,
-+                 GAsyncResult *res,
-+                 gpointer      user_data)
-+{
-+  MetaBackend *backend;
-+  MetaBackendPrivate *priv;
-+  GDBusProxy *proxy;
-+  GError *error = NULL;
-+  GVariant *v;
-+
-+  proxy = g_dbus_proxy_new_finish (res, &error);
-+  if (!proxy)
-+    {
-+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-+        g_warning ("Failed to create UPower proxy: %s", error->message);
-+      g_error_free (error);
-+      return;
-+    }
-+
-+  backend = META_BACKEND (user_data);
-+  priv = meta_backend_get_instance_private (backend);
-+
-+  priv->upower_proxy = proxy;
-+  g_signal_connect (proxy, "g-properties-changed",
-+                    G_CALLBACK (upower_properties_changed), backend);
-+
-+  v = g_dbus_proxy_get_cached_property (proxy, "LidIsClosed");
-+  if (v)
-+    {
-+      priv->lid_is_closed = g_variant_get_boolean (v);
-+      g_variant_unref (v);
-+
-+      if (priv->lid_is_closed)
-+        {
-+          g_signal_emit (backend, signals[LID_IS_CLOSED_CHANGED], 0,
-+                         priv->lid_is_closed);
-+        }
-+    }
-+
-+  v = g_dbus_proxy_get_cached_property (proxy, "OnBattery");
-+  if (v)
-+    {
-+      priv->on_battery = g_variant_get_boolean (v);
-+      g_variant_unref (v);
-+    }
-+}
-+
-+static void
-+upower_appeared (GDBusConnection *connection,
-+                 const gchar     *name,
-+                 const gchar     *name_owner,
-+                 gpointer         user_data)
-+{
-+  MetaBackend *backend = META_BACKEND (user_data);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  g_dbus_proxy_new (connection,
-+                    G_DBUS_PROXY_FLAGS_NONE,
-+                    NULL,
-+                    "org.freedesktop.UPower",
-+                    "/org/freedesktop/UPower",
-+                    "org.freedesktop.UPower",
-+                    priv->cancellable,
-+                    upower_ready_cb,
-+                    backend);
-+}
-+
-+static void
-+upower_vanished (GDBusConnection *connection,
-+                 const gchar     *name,
-+                 gpointer         user_data)
-+{
-+  MetaBackend *backend = META_BACKEND (user_data);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  g_clear_object (&priv->upower_proxy);
-+}
-+
-+static void
-+meta_backend_constructed (GObject *object)
-+{
-+  MetaBackend *backend = META_BACKEND (object);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  MetaBackendClass *backend_class =
-+   META_BACKEND_GET_CLASS (backend);
-+
-+  g_assert (priv->context);
-+
-+#ifdef HAVE_LIBWACOM
-+  priv->wacom_db = libwacom_database_new ();
-+  if (!priv->wacom_db)
-+    {
-+      g_warning ("Could not create database of Wacom devices, "
-+                 "expect tablets to misbehave");
-+    }
-+#endif
-+
-+  if (backend_class->is_lid_closed == meta_backend_real_is_lid_closed)
-+    {
-+      priv->upower_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
-+                                                "org.freedesktop.UPower",
-+                                                G_BUS_NAME_WATCHER_FLAGS_NONE,
-+                                                upower_appeared,
-+                                                upower_vanished,
-+                                                backend,
-+                                                NULL);
-+    }
-+
-+#ifdef HAVE_EGL
-+  priv->egl = g_object_new (META_TYPE_EGL, NULL);
-+#endif
-+
-+  G_OBJECT_CLASS (meta_backend_parent_class)->constructed (object);
-+}
-+
-+static void
-+meta_backend_set_property (GObject      *object,
-+                           guint         prop_id,
-+                           const GValue *value,
-+                           GParamSpec   *pspec)
-+{
-+  MetaBackend *backend = META_BACKEND (object);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  switch (prop_id)
-+    {
-+    case PROP_CONTEXT:
-+      priv->context = g_value_get_object (value);
-+      break;
-+    default:
-+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+      break;
-+    }
-+}
-+
-+static void
-+meta_backend_get_property (GObject    *object,
-+                           guint       prop_id,
-+                           GValue     *value,
-+                           GParamSpec *pspec)
-+{
-+  MetaBackend *backend = META_BACKEND (object);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  switch (prop_id)
-+    {
-+    case PROP_CONTEXT:
-+      g_value_set_object (value, priv->context);
-+      break;
-+    case PROP_CAPABILITIES:
-+      g_value_set_flags (value, meta_backend_get_capabilities (backend));
-+      break;
-+    default:
-+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+      break;
-+    }
-+}
-+
-+static void
-+meta_backend_class_init (MetaBackendClass *klass)
-+{
-+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-+
-+  object_class->dispose = meta_backend_dispose;
-+  object_class->constructed = meta_backend_constructed;
-+  object_class->set_property = meta_backend_set_property;
-+  object_class->get_property = meta_backend_get_property;
-+
-+  klass->post_init = meta_backend_real_post_init;
-+  klass->grab_device = meta_backend_real_grab_device;
-+  klass->ungrab_device = meta_backend_real_ungrab_device;
-+  klass->select_stage_events = meta_backend_real_select_stage_events;
-+  klass->is_lid_closed = meta_backend_real_is_lid_closed;
-+  klass->create_cursor_tracker = meta_backend_real_create_cursor_tracker;
-+  klass->is_headless = meta_backend_real_is_headless;
-+
-+  obj_props[PROP_CONTEXT] =
-+    g_param_spec_object ("context",
-+                         "context",
-+                         "MetaContext",
-+                         META_TYPE_CONTEXT,
-+                         G_PARAM_READWRITE |
-+                         G_PARAM_CONSTRUCT_ONLY |
-+                         G_PARAM_STATIC_STRINGS);
-+  obj_props[PROP_CAPABILITIES] =
-+    g_param_spec_flags ("capabilities",
-+                        "capabilities",
-+                        "Backend capabilities",
-+                        META_TYPE_BACKEND_CAPABILITIES,
-+                        META_BACKEND_CAPABILITY_NONE,
-+                        G_PARAM_READABLE |
-+                        G_PARAM_STATIC_STRINGS);
-+  g_object_class_install_properties (object_class, N_PROPS, obj_props);
-+
-+  signals[KEYMAP_CHANGED] =
-+    g_signal_new ("keymap-changed",
-+                  G_TYPE_FROM_CLASS (object_class),
-+                  G_SIGNAL_RUN_LAST,
-+                  0,
-+                  NULL, NULL, NULL,
-+                  G_TYPE_NONE, 0);
-+  signals[KEYMAP_LAYOUT_GROUP_CHANGED] =
-+    g_signal_new ("keymap-layout-group-changed",
-+                  G_TYPE_FROM_CLASS (object_class),
-+                  G_SIGNAL_RUN_LAST,
-+                  0,
-+                  NULL, NULL, NULL,
-+                  G_TYPE_NONE, 1, G_TYPE_UINT);
-+  signals[LAST_DEVICE_CHANGED] =
-+    g_signal_new ("last-device-changed",
-+                  G_TYPE_FROM_CLASS (object_class),
-+                  G_SIGNAL_RUN_LAST,
-+                  0,
-+                  NULL, NULL, NULL,
-+                  G_TYPE_NONE, 1, CLUTTER_TYPE_INPUT_DEVICE);
-+  signals[LID_IS_CLOSED_CHANGED] =
-+    g_signal_new ("lid-is-closed-changed",
-+                  G_TYPE_FROM_CLASS (object_class),
-+                  G_SIGNAL_RUN_LAST,
-+                  0,
-+                  NULL, NULL, NULL,
-+                  G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-+  /**
-+   * MetaBackend::gpu-added: (skip)
-+   * @backend: the #MetaBackend
-+   * @gpu: the #MetaGpu
-+   */
-+  signals[GPU_ADDED] =
-+    g_signal_new ("gpu-added",
-+                  G_TYPE_FROM_CLASS (klass),
-+                  G_SIGNAL_RUN_LAST,
-+                  0,
-+                  NULL, NULL, NULL,
-+                  G_TYPE_NONE, 1, META_TYPE_GPU);
-+  signals[PREPARE_SHUTDOWN] =
-+    g_signal_new ("prepare-shutdown",
-+                  G_TYPE_FROM_CLASS (klass),
-+                  G_SIGNAL_RUN_LAST,
-+                  0,
-+                  NULL, NULL, NULL,
-+                  G_TYPE_NONE, 0);
-+}
-+
-+static MetaMonitorManager *
-+meta_backend_create_monitor_manager (MetaBackend *backend,
-+                                     GError     **error)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend,
-+                                                                   error);
-+}
-+
-+static MetaColorManager *
-+meta_backend_create_color_manager (MetaBackend *backend)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->create_color_manager (backend);
-+}
-+
-+static MetaRenderer *
-+meta_backend_create_renderer (MetaBackend *backend,
-+                              GError     **error)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
-+}
-+
-+static void
-+prepare_for_sleep_cb (GDBusConnection *connection,
-+                      const gchar     *sender_name,
-+                      const gchar     *object_path,
-+                      const gchar     *interface_name,
-+                      const gchar     *signal_name,
-+                      GVariant        *parameters,
-+                      gpointer         user_data)
-+{
-+  MetaBackend *backend = user_data;
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  gboolean suspending;
-+
-+  g_variant_get (parameters, "(b)", &suspending);
-+  if (suspending)
-+    return;
-+
-+  meta_idle_manager_reset_idle_time (priv->idle_manager);
-+}
-+
-+static void
-+system_bus_gotten_cb (GObject      *object,
-+                      GAsyncResult *res,
-+                      gpointer      user_data)
-+{
-+  MetaBackend *backend = user_data;
-+  MetaBackendPrivate *priv;
-+  GDBusConnection *bus;
-+
-+  bus = g_bus_get_finish (res, NULL);
-+  if (!bus)
-+    return;
-+
-+  priv = meta_backend_get_instance_private (backend);
-+  priv->system_bus = bus;
-+  priv->sleep_signal_id =
-+    g_dbus_connection_signal_subscribe (priv->system_bus,
-+                                        "org.freedesktop.login1",
-+                                        "org.freedesktop.login1.Manager",
-+                                        "PrepareForSleep",
-+                                        "/org/freedesktop/login1",
-+                                        NULL,
-+                                        G_DBUS_SIGNAL_FLAGS_NONE,
-+                                        prepare_for_sleep_cb,
-+                                        backend,
-+                                        NULL);
-+}
-+
-+static void
-+update_last_device_from_event (MetaBackend  *backend,
-+                               ClutterEvent *event)
-+{
-+  ClutterInputDevice *source;
-+
-+  /* Handled elsewhere */
-+  if (event->type == CLUTTER_DEVICE_ADDED ||
-+      event->type == CLUTTER_DEVICE_REMOVED)
-+    return;
-+
-+  source = clutter_event_get_source_device (event);
-+  if (source)
-+    meta_backend_update_last_device (backend, source);
-+}
-+
-+static void
-+update_pointer_visibility_from_event (MetaBackend  *backend,
-+                                      ClutterEvent *event)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  MetaCursorTracker *cursor_tracker = priv->cursor_tracker;
-+  ClutterInputDevice *device;
-+  ClutterInputDeviceType device_type;
-+  uint32_t time_ms;
-+
-+  device = clutter_event_get_source_device (event);
-+  device_type = clutter_input_device_get_device_type (device);
-+  time_ms = clutter_event_get_time (event);
-+
-+  switch (device_type)
-+    {
-+    case CLUTTER_TOUCHSCREEN_DEVICE:
-+      meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
-+      break;
-+    case CLUTTER_POINTER_DEVICE:
-+    case CLUTTER_TOUCHPAD_DEVICE:
-+      priv->last_pointer_motion = time_ms;
-+      meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE);
-+      break;
-+    case CLUTTER_TABLET_DEVICE:
-+    case CLUTTER_PEN_DEVICE:
-+    case CLUTTER_ERASER_DEVICE:
-+    case CLUTTER_CURSOR_DEVICE:
-+      if (meta_is_wayland_compositor () &&
-+          time_ms > priv->last_pointer_motion + HIDDEN_POINTER_TIMEOUT)
-+        meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
-+      break;
-+    case CLUTTER_KEYBOARD_DEVICE:
-+    case CLUTTER_PAD_DEVICE:
-+    case CLUTTER_EXTENSION_DEVICE:
-+    case CLUTTER_JOYSTICK_DEVICE:
-+    default:
-+      break;
-+    }
-+}
-+
-+/* Mutter is responsible for pulling events off the X queue, so Clutter
-+ * doesn't need (and shouldn't) run its normal event source which polls
-+ * the X fd, but we do have to deal with dispatching events that accumulate
-+ * in the clutter queue. This happens, for example, when clutter generate
-+ * enter/leave events on mouse motion - several events are queued in the
-+ * clutter queue but only one dispatched. It could also happen because of
-+ * explicit calls to clutter_event_put(). We add a very simple custom
-+ * event loop source which is simply responsible for pulling events off
-+ * of the queue and dispatching them before we block for new events.
-+ */
-+
-+static gboolean
-+clutter_source_prepare (GSource *source,
-+                        int     *timeout)
-+{
-+  *timeout = -1;
-+
-+  return clutter_events_pending ();
-+}
-+
-+static gboolean
-+clutter_source_check (GSource *source)
-+{
-+  return clutter_events_pending ();
-+}
-+
-+static gboolean
-+clutter_source_dispatch (GSource     *source,
-+                         GSourceFunc  callback,
-+                         gpointer     user_data)
-+{
-+  MetaBackendSource *backend_source = (MetaBackendSource *) source;
-+  ClutterEvent *event = clutter_event_get ();
-+
-+  if (event)
-+    {
-+      event->any.stage =
-+        CLUTTER_STAGE (meta_backend_get_stage (backend_source->backend));
-+      clutter_do_event (event);
-+      meta_backend_update_from_event (backend_source->backend, event);
-+      clutter_event_free (event);
-+    }
-+
-+  return TRUE;
-+}
-+
-+static GSourceFuncs clutter_source_funcs = {
-+  clutter_source_prepare,
-+  clutter_source_check,
-+  clutter_source_dispatch
-+};
-+
-+static ClutterBackend *
-+meta_clutter_backend_constructor (gpointer user_data)
-+{
-+  MetaBackend *backend = META_BACKEND (user_data);
-+
-+  return META_BACKEND_GET_CLASS (backend)->create_clutter_backend (backend);
-+}
-+
-+static ClutterSeat *
-+meta_backend_create_default_seat (MetaBackend  *backend,
-+                                  GError      **error)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->create_default_seat (backend, error);
-+}
-+
-+static gboolean
-+init_clutter (MetaBackend  *backend,
-+              GError      **error)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  MetaBackendSource *backend_source;
-+  GSource *source;
-+
-+  priv->clutter_context = clutter_context_new (meta_clutter_backend_constructor,
-+                                               backend,
-+                                               error);
-+  if (!priv->clutter_context)
-+    return FALSE;
-+
-+  priv->default_seat = meta_backend_create_default_seat (backend, error);
-+  if (!priv->default_seat)
-+    return FALSE;
-+
-+  source = g_source_new (&clutter_source_funcs, sizeof (MetaBackendSource));
-+  g_source_set_name (source, "[mutter] Backend");
-+  backend_source = (MetaBackendSource *) source;
-+  backend_source->backend = backend;
-+  g_source_attach (source, NULL);
-+  g_source_unref (source);
-+
-+  return TRUE;
-+}
-+
-+static void
-+meta_backend_post_init (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  META_BACKEND_GET_CLASS (backend)->post_init (backend);
-+
-+  meta_settings_post_init (priv->settings);
-+}
-+
-+static gboolean
-+meta_backend_initable_init (GInitable     *initable,
-+                            GCancellable  *cancellable,
-+                            GError       **error)
-+{
-+  MetaBackend *backend = META_BACKEND (initable);
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  priv->settings = meta_settings_new (backend);
-+  priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL);
-+
-+  priv->monitor_manager = meta_backend_create_monitor_manager (backend, error);
-+  if (!priv->monitor_manager)
-+    return FALSE;
-+
-+  priv->color_manager = meta_backend_create_color_manager (backend);
-+
-+  priv->renderer = meta_backend_create_renderer (backend, error);
-+  if (!priv->renderer)
-+    return FALSE;
-+
-+  priv->cursor_tracker =
-+    META_BACKEND_GET_CLASS (backend)->create_cursor_tracker (backend);
-+
-+  priv->dnd = meta_dnd_new (backend);
-+
-+  priv->cancellable = g_cancellable_new ();
-+  g_bus_get (G_BUS_TYPE_SYSTEM,
-+             priv->cancellable,
-+             system_bus_gotten_cb,
-+             backend);
-+
-+  if (!init_clutter (backend, error))
-+    return FALSE;
-+
-+  meta_backend_post_init (backend);
-+
-+  return TRUE;
-+}
-+
-+static void
-+initable_iface_init (GInitableIface *initable_iface)
-+{
-+  initable_iface->init = meta_backend_initable_init;
-+}
-+
-+static void
-+meta_backend_init (MetaBackend *backend)
-+{
-+}
-+
-+/**
-+ * meta_backend_get_idle_monitor: (skip)
-+ */
-+MetaIdleMonitor *
-+meta_backend_get_idle_monitor (MetaBackend        *backend,
-+                               ClutterInputDevice *device)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return meta_idle_manager_get_monitor (priv->idle_manager, device);
-+}
-+
-+/**
-+ * meta_backend_get_core_idle_monitor:
-+ *
-+ * Returns: (transfer none): the #MetaIdleMonitor that tracks server-global
-+ * idle time for all devices.
-+ */
-+MetaIdleMonitor *
-+meta_backend_get_core_idle_monitor (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return meta_idle_manager_get_core_monitor (priv->idle_manager);
-+}
-+
-+/**
-+ * meta_backend_get_idle_manager: (skip)
-+ */
-+MetaIdleManager *
-+meta_backend_get_idle_manager (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->idle_manager;
-+}
-+
-+/**
-+ * meta_backend_get_monitor_manager:
-+ *
-+ * Returns: (transfer none): A #MetaMonitorManager
-+ */
-+MetaMonitorManager *
-+meta_backend_get_monitor_manager (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->monitor_manager;
-+}
-+
-+/**
-+ * meta_backend_get_color_manager: (skip)
-+ */
-+MetaColorManager *
-+meta_backend_get_color_manager (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->color_manager;
-+}
-+
-+/**
-+ * meta_backend_get_orientation_manager: (skip)
-+ */
-+MetaOrientationManager *
-+meta_backend_get_orientation_manager (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->orientation_manager;
-+}
-+
-+MetaCursorTracker *
-+meta_backend_get_cursor_tracker (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->cursor_tracker;
-+}
-+
-+/**
-+ * meta_backend_get_cursor_renderer: (skip)
-+ */
-+MetaCursorRenderer *
-+meta_backend_get_cursor_renderer (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  ClutterInputDevice *pointer;
-+
-+  if (!priv->default_seat)
-+    return NULL;
-+
-+  pointer = clutter_seat_get_pointer (priv->default_seat);
-+
-+  return meta_backend_get_cursor_renderer_for_device (backend, pointer);
-+}
-+
-+MetaCursorRenderer *
-+meta_backend_get_cursor_renderer_for_device (MetaBackend        *backend,
-+                                             ClutterInputDevice *device)
-+{
-+  g_return_val_if_fail (META_IS_BACKEND (backend), NULL);
-+  g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
-+  g_return_val_if_fail (clutter_input_device_get_device_type (device) !=
-+                        CLUTTER_KEYBOARD_DEVICE, NULL);
-+
-+  return META_BACKEND_GET_CLASS (backend)->get_cursor_renderer (backend,
-+                                                                device);
-+}
-+
-+/**
-+ * meta_backend_get_renderer: (skip)
-+ */
-+MetaRenderer *
-+meta_backend_get_renderer (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->renderer;
-+}
-+
-+#ifdef HAVE_EGL
-+/**
-+ * meta_backend_get_egl: (skip)
-+ */
-+MetaEgl *
-+meta_backend_get_egl (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->egl;
-+}
-+#endif /* HAVE_EGL */
-+
-+/**
-+ * meta_backend_get_settings: (skip)
-+ */
-+MetaSettings *
-+meta_backend_get_settings (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->settings;
-+}
-+
-+MetaDbusSessionWatcher *
-+meta_backend_get_dbus_session_watcher (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->dbus_session_watcher;
-+}
-+
-+#ifdef HAVE_REMOTE_DESKTOP
-+/**
-+ * meta_backend_get_remote_desktop: (skip)
-+ */
-+MetaRemoteDesktop *
-+meta_backend_get_remote_desktop (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->remote_desktop;
-+}
-+
-+/**
-+ * meta_backend_get_screen_cast: (skip)
-+ */
-+MetaScreenCast *
-+meta_backend_get_screen_cast (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->screen_cast;
-+}
-+#endif /* HAVE_REMOTE_DESKTOP */
-+
-+/**
-+ * meta_backend_get_remote_access_controller:
-+ * @backend: A #MetaBackend
-+ *
-+ * Return Value: (transfer none): The #MetaRemoteAccessController
-+ */
-+MetaRemoteAccessController *
-+meta_backend_get_remote_access_controller (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->remote_access_controller;
-+}
-+
-+/**
-+ * meta_backend_is_rendering_hardware_accelerated:
-+ * @backend: A #MetaBackend
-+ *
-+ * Returns: %TRUE if the rendering is hardware accelerated, otherwise
-+ * %FALSE.
-+ */
-+gboolean
-+meta_backend_is_rendering_hardware_accelerated (MetaBackend *backend)
-+{
-+  MetaRenderer *renderer = meta_backend_get_renderer (backend);
-+
-+  return meta_renderer_is_hardware_accelerated (renderer);
-+}
-+
-+/**
-+ * meta_backend_grab_device: (skip)
-+ */
-+gboolean
-+meta_backend_grab_device (MetaBackend *backend,
-+                          int          device_id,
-+                          uint32_t     timestamp)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->grab_device (backend, device_id, timestamp);
-+}
-+
-+/**
-+ * meta_backend_get_context:
-+ * @backend: the #MetaBackend
-+ *
-+ * Returns: (transfer none): The #MetaContext
-+ */
-+MetaContext *
-+meta_backend_get_context (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->context;
-+}
-+
-+/**
-+ * meta_backend_ungrab_device: (skip)
-+ */
-+gboolean
-+meta_backend_ungrab_device (MetaBackend *backend,
-+                            int          device_id,
-+                            uint32_t     timestamp)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
-+}
-+
-+/**
-+ * meta_backend_finish_touch_sequence: (skip)
-+ */
-+void
-+meta_backend_finish_touch_sequence (MetaBackend          *backend,
-+                                    ClutterEventSequence *sequence,
-+                                    MetaSequenceState     state)
-+{
-+  if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence)
-+    META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend,
-+                                                             sequence,
-+                                                             state);
-+}
-+
-+MetaLogicalMonitor *
-+meta_backend_get_current_logical_monitor (MetaBackend *backend)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->get_current_logical_monitor (backend);
-+}
-+
-+void
-+meta_backend_set_keymap (MetaBackend *backend,
-+                         const char  *layouts,
-+                         const char  *variants,
-+                         const char  *options)
-+{
-+  META_BACKEND_GET_CLASS (backend)->set_keymap (backend, layouts, variants, options);
-+}
-+
-+/**
-+ * meta_backend_get_keymap: (skip)
-+ */
-+struct xkb_keymap *
-+meta_backend_get_keymap (MetaBackend *backend)
-+
-+{
-+  return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
-+}
-+
-+xkb_layout_index_t
-+meta_backend_get_keymap_layout_group (MetaBackend *backend)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->get_keymap_layout_group (backend);
-+}
-+
-+void
-+meta_backend_lock_layout_group (MetaBackend *backend,
-+                                guint idx)
-+{
-+  META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx);
-+}
-+
-+/**
-+ * meta_backend_get_stage:
-+ * @backend: A #MetaBackend
-+ *
-+ * Gets the global #ClutterStage that's managed by this backend.
-+ *
-+ * Returns: (transfer none): the #ClutterStage
-+ */
-+ClutterActor *
-+meta_backend_get_stage (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  return priv->stage;
-+}
-+
-+ClutterSeat *
-+meta_backend_get_default_seat (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->default_seat;
-+}
-+
-+MetaPointerConstraint *
-+meta_backend_get_client_pointer_constraint (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->client_pointer_constraint;
-+}
-+
-+/**
-+ * meta_backend_set_client_pointer_constraint:
-+ * @backend: a #MetaBackend object.
-+ * @constraint: (nullable): the client constraint to follow.
-+ *
-+ * Sets the current pointer constraint and removes (and unrefs) the previous
-+ * one. If @constraint is %NULL, this means that there is no
-+ * #MetaPointerConstraint active.
-+ */
-+void
-+meta_backend_set_client_pointer_constraint (MetaBackend           *backend,
-+                                            MetaPointerConstraint *constraint)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  META_BACKEND_GET_CLASS (backend)->set_pointer_constraint (backend, constraint);
-+  g_set_object (&priv->client_pointer_constraint, constraint);
-+}
-+
-+ClutterBackend *
-+meta_backend_get_clutter_backend (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  ClutterContext *clutter_context;
-+
-+  clutter_context = priv->clutter_context;
-+  if (!clutter_context)
-+    return NULL;
-+
-+  return clutter_context_get_backend (clutter_context);
-+}
-+
-+MetaBackendCapabilities
-+meta_backend_get_capabilities (MetaBackend *backend)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->get_capabilities (backend);
-+}
-+
-+gboolean
-+meta_backend_is_stage_views_scaled (MetaBackend *backend)
-+{
-+  MetaMonitorManager *monitor_manager =
-+    meta_backend_get_monitor_manager (backend);
-+  MetaLogicalMonitorLayoutMode layout_mode;
-+
-+  layout_mode = monitor_manager->layout_mode;
-+
-+  return layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
-+}
-+
-+MetaInputMapper *
-+meta_backend_get_input_mapper (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->input_mapper;
-+}
-+
-+MetaInputSettings *
-+meta_backend_get_input_settings (MetaBackend *backend)
-+{
-+  return META_BACKEND_GET_CLASS (backend)->get_input_settings (backend);
-+}
-+
-+/**
-+ * meta_backend_get_dnd:
-+ * @backend: A #MetaDnd
-+ *
-+ * Gets the global #MetaDnd that's managed by this backend.
-+ *
-+ * Returns: (transfer none): the #MetaDnd
-+ */
-+MetaDnd *
-+meta_backend_get_dnd (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->dnd;
-+}
-+
-+void
-+meta_backend_notify_keymap_changed (MetaBackend *backend)
-+{
-+  g_signal_emit (backend, signals[KEYMAP_CHANGED], 0);
-+}
-+
-+void
-+meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend,
-+                                                 unsigned int locked_group)
-+{
-+  g_signal_emit (backend, signals[KEYMAP_LAYOUT_GROUP_CHANGED], 0,
-+                 locked_group);
-+}
-+
-+void
-+meta_backend_add_gpu (MetaBackend *backend,
-+                      MetaGpu     *gpu)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  priv->gpus = g_list_append (priv->gpus, gpu);
-+
-+  g_signal_emit (backend, signals[GPU_ADDED], 0, gpu);
-+}
-+
-+GList *
-+meta_backend_get_gpus (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->gpus;
-+}
-+
-+#ifdef HAVE_LIBWACOM
-+WacomDeviceDatabase *
-+meta_backend_get_wacom_database (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  return priv->wacom_db;
-+}
-+#endif
-+
-+void
-+meta_backend_add_hw_cursor_inhibitor (MetaBackend           *backend,
-+                                      MetaHwCursorInhibitor *inhibitor)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  priv->hw_cursor_inhibitors = g_list_prepend (priv->hw_cursor_inhibitors,
-+                                               inhibitor);
-+}
-+
-+void
-+meta_backend_remove_hw_cursor_inhibitor (MetaBackend           *backend,
-+                                         MetaHwCursorInhibitor *inhibitor)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  priv->hw_cursor_inhibitors = g_list_remove (priv->hw_cursor_inhibitors,
-+                                              inhibitor);
-+}
-+
-+gboolean
-+meta_backend_is_hw_cursors_inhibited (MetaBackend *backend)
-+{
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+  GList *l;
-+
-+  for (l = priv->hw_cursor_inhibitors; l; l = l->next)
-+    {
-+      MetaHwCursorInhibitor *inhibitor = l->data;
-+
-+      if (meta_hw_cursor_inhibitor_is_cursor_inhibited (inhibitor))
-+        return TRUE;
-+    }
-+
-+  return FALSE;
-+}
-+
-+void
-+meta_backend_update_from_event (MetaBackend  *backend,
-+                                ClutterEvent *event)
-+{
-+  update_last_device_from_event (backend, event);
-+  update_pointer_visibility_from_event (backend, event);
-+}
-+
-+/**
-+ * meta_backend_get_vendor_name:
-+ * @backend: A #MetaBackend object
-+ * @pnp_id: the PNP ID
-+ *
-+ * Find the full vendor name from the given PNP ID.
-+ *
-+ * Returns: (transfer full): A string containing the vendor name,
-+ *                           or NULL when not found.
-+ */
-+char *
-+meta_backend_get_vendor_name (MetaBackend *backend,
-+                              const char  *pnp_id)
-+{
-+#ifdef HAVE_GNOME_DESKTOP
-+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-+
-+  if (!priv->pnp_ids)
-+    priv->pnp_ids = gnome_pnp_ids_new ();
-+
-+  return gnome_pnp_ids_get_pnp_id (priv->pnp_ids, pnp_id);
-+#else
-+  return g_strdup (pnp_id);
-+#endif
-+}
 -- 
-2.41.0
+GitLab
 
diff --git a/mutter/mutter.spec b/mutter/mutter.spec
index 6c47caa..73c748e 100644
--- a/mutter/mutter.spec
+++ b/mutter/mutter.spec
@@ -11,11 +11,11 @@
 
 
 %global gnome_major_version 44
-%global gnome_version %{gnome_major_version}.2
+%global gnome_version %{gnome_major_version}.3
 %global tarball_version %%(echo %{gnome_version} | tr '~' '.')
 
 Name:          mutter
-Version:       %{gnome_version}.vrr.15
+Version:       %{gnome_version}.vrr.1
 Release:       1%{?dist}
 Summary:       Window and compositing manager based on Clutter
 
@@ -23,20 +23,17 @@ License:       GPLv2+
 URL:           https://www.gnome.org
 Source0:       https://download.gnome.org/sources/%{name}/%{gnome_major_version}/%{name}-%{tarball_version}.tar.xz
 
-# Work-around for OpenJDK's compliance test
 Patch0:        0001-window-actor-Special-case-shaped-Java-windows.patch
-
-# https://bugzilla.redhat.com/show_bug.cgi?id=1936991
 Patch1:        mutter-42.alpha-disable-tegra.patch
-
-# https://pagure.io/fedora-workstation/issue/79
 Patch2:        0001-place-Always-center-initial-setup-fedora-welcome.patch
-
-# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154
 Patch3:        1154.patch
-Patch4:        3080.patch
-Patch5:        3085.patch
-Patch6:        enable-vrr-setting.patch
+Patch4:        3085.patch
+Patch5:        enable-vrr-setting.patch
+Patch6:	       3035.patch
+Patch7:	       3096.patch
+Patch8:	       3113.patch
+Patch9:	       3117.patch
+Patch10:       3125.patch
 
 BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.41.0
 BuildRequires: pkgconfig(sm)
 

I tried to combine your changes with those of patrickl's copr

I've seen that the mr 3080 already got merged into 44.3 and removed that patch but it appears 3085 got altered as well to make the vrr patches work again...

Support for Rawhide

Hello!

I run rawhide on my system and I'm trying to figure out how to use your repo as a blueprint to make my own. I'm interested in maintaining a rawhide repo. Looking for ideas on how to start. Are you manually coping patches into this git repo from dor's?

Thanks for any help. Feel free to shoo me away. :)

Gnome 45 support

I just spent a bit rebasing and reworking the patch to work with mutter 45. The gnome-control-center bits worked fine with the same patch as before but mutter needed some finagling.

Since you need to make a new f39 branch I didn't open a PR for this.

Also Github doesn't let you upload .patch files I guess so it's just a .txt.
myvrr_patch.txt

Support for F37

Seems we are waiting for gnome to still implement these fixes, for users trying out F37 Beta would love to be able to use your copr to install these patches.

Mutter 44

Hi, I maintain the mutter-vrr AUR package. I've began attempting to rebase on 44, and it seems it will take a little work. Curious if you've had a chance to poke at it yet

CentOS stream COPR support

Hello! I use and appreciate this COPR heavily on fedora systems, and was wondering if there was a way to build the COPR against CentOS Stream as well. If an official maintained branch is out of scope I will attempt to do myself, though I must admit I am rather new to dealing with .rpms. Thanks in advance!

Upstream updates override the vrr packages (dnf priority fix)

Just a small issue, with a note on how to address it. Every time actual mutter or gnome-control-center has an update, VRR package is overwritten. Hence every update VRR breaks until the VRR repo is updated again.

This can be prevented by granting the VRR repo higher priority than the official repo. This is done by setting the priority option of the repository to 1. This will grant the repo higher priority than the official (defaulting to priority 99 I think, so 98 should already work). All packages in the gnome-vrr repository (mutter, gnome-control-center) will now have higher priority, even if they are of a lower version.

sudo dnf config-manager --save --setopt="copr:copr.fedorainfracloud.org:kylegospo:gnome-vrr.priority=1"

As it is currently the case with the latest mutter update, I also tested this. Software center showed an update to the non-VRR mutter. However, after setting this priority, there is no update found anymore (as expected).

Final note: I am not experienced with dnf that much. I just got annoyed by vrr breaking every time and this fixed it for me. So if there are downsides to this approach, I am not familiar with them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.