1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <glib.h>
#include <gio/gio.h>

#include "cdkmonitor-x11.h"
#include "cdkscreen-x11.h"


G_DEFINE_TYPE (CdkX11Monitor, cdk_x11_monitor, CDK_TYPE_MONITOR)

static gboolean
cdk_monitor_has_fullscreen_window (CdkMonitor *monitor)
{
  CdkScreen *screen = cdk_display_get_default_screen (monitor->display);
  GList *toplevels, *l;
  CdkWindow *window;
  gboolean has_fullscreen;

  toplevels = cdk_screen_get_toplevel_windows (screen);

  has_fullscreen = FALSE;
  for (l = toplevels; l; l = l->next)
    {
      window = l->data;

      if ((cdk_window_get_state (window) & CDK_WINDOW_STATE_FULLSCREEN) == 0)
        continue;

      if (cdk_window_get_fullscreen_mode (window) == CDK_FULLSCREEN_ON_ALL_MONITORS ||
          cdk_display_get_monitor_at_window (monitor->display, window) == monitor)
        {
          has_fullscreen = TRUE;
          break;
        }
    }

  g_list_free (toplevels);

  return has_fullscreen;
}

static void
cdk_x11_monitor_get_workarea (CdkMonitor   *monitor,
                              CdkRectangle *dest)
{
  CdkScreen *screen = cdk_display_get_default_screen (monitor->display);
  CdkRectangle workarea;

  cdk_monitor_get_geometry (monitor, dest);

  if (_cdk_x11_screen_get_monitor_work_area (screen, monitor, &workarea))
    {
      if (!cdk_monitor_has_fullscreen_window (monitor))
        *dest = workarea;
    }
  else
    {
      /* The EWMH constrains workarea to be a rectangle, so it
       * can't adequately deal with L-shaped monitor arrangements.
       * As a workaround, we ignore the workarea for anything
       * but the primary monitor. Since that is where the 'desktop
       * chrome' usually lives, this works ok in practice.
       */
      if (cdk_monitor_is_primary (monitor) &&
          !cdk_monitor_has_fullscreen_window (monitor))
        {
          cdk_x11_screen_get_work_area (screen, &workarea);
          if (cdk_rectangle_intersect (dest, &workarea, &workarea))
            *dest = workarea;
        }
    }
}

static void
cdk_x11_monitor_init (CdkX11Monitor *monitor G_GNUC_UNUSED)<--- Parameter 'G_GNUC_UNUSED' can be declared as pointer to const
{
}

static void
cdk_x11_monitor_class_init (CdkX11MonitorClass *class)
{
  CDK_MONITOR_CLASS (class)->get_workarea = cdk_x11_monitor_get_workarea;
}

XID
cdk_x11_monitor_get_output (CdkMonitor *monitor)
{
  g_return_val_if_fail (CDK_IS_X11_MONITOR (monitor), 0);

  return CDK_X11_MONITOR (monitor)->output;
}