You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

156 lines
4.2 KiB

  1. #include <config.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <gdk/gdkx.h>
  6. #include <gtk/gtk.h>
  7. #include <glib/gi18n-lib.h>
  8. #include "xapp-monitor-blanker.h"
  9. struct _XAppMonitorBlankerPrivate
  10. {
  11. int num_outputs;
  12. gboolean blanked;
  13. GtkWidget **windows;
  14. };
  15. G_DEFINE_TYPE (XAppMonitorBlanker, xapp_monitor_blanker, G_TYPE_OBJECT);
  16. GtkWidget *create_blanking_window (GdkScreen *screen,
  17. int monitor);
  18. static void
  19. xapp_monitor_blanker_init (XAppMonitorBlanker *self)
  20. {
  21. self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, XAPP_TYPE_MONITOR_BLANKER, XAppMonitorBlankerPrivate);
  22. self->priv->num_outputs = 0;
  23. self->priv->blanked = FALSE;
  24. self->priv->windows = NULL;
  25. }
  26. static void
  27. xapp_monitor_blanker_finalize (GObject *object)
  28. {
  29. XAppMonitorBlanker *self = XAPP_MONITOR_BLANKER (object);
  30. if (self->priv->windows != NULL)
  31. {
  32. xapp_monitor_blanker_unblank_monitors (XAPP_MONITOR_BLANKER(self));
  33. g_free (self->priv->windows);
  34. }
  35. G_OBJECT_CLASS (xapp_monitor_blanker_parent_class)->finalize (object);
  36. }
  37. static void
  38. xapp_monitor_blanker_class_init (XAppMonitorBlankerClass *klass)
  39. {
  40. GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  41. gobject_class->finalize = xapp_monitor_blanker_finalize;
  42. g_type_class_add_private (gobject_class, sizeof (XAppMonitorBlankerPrivate));
  43. }
  44. XAppMonitorBlanker *
  45. xapp_monitor_blanker_new (void)
  46. {
  47. return g_object_new (XAPP_TYPE_MONITOR_BLANKER, NULL);
  48. }
  49. GtkWidget *
  50. create_blanking_window (GdkScreen *screen,
  51. int monitor)
  52. {
  53. GdkRectangle fullscreen;
  54. GtkWidget *window;
  55. GtkStyleContext *context;
  56. GtkCssProvider *provider;
  57. gdk_screen_get_monitor_geometry(screen, monitor, &fullscreen);
  58. window = gtk_window_new (GTK_WINDOW_POPUP);
  59. gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
  60. gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
  61. gtk_window_resize (GTK_WINDOW (window), fullscreen.width, fullscreen.height);
  62. gtk_window_move (GTK_WINDOW (window), fullscreen.x, fullscreen.y);
  63. gtk_widget_set_visible (window, TRUE);
  64. context = gtk_widget_get_style_context (GTK_WIDGET (window));
  65. gtk_style_context_add_class (context, "xapp-blanking-window");
  66. provider = gtk_css_provider_new ();
  67. gtk_css_provider_load_from_data (provider,
  68. ".xapp-blanking-window { background-color: rgb(0, 0, 0); }",
  69. -1, NULL);
  70. gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
  71. return window;
  72. }
  73. void
  74. xapp_monitor_blanker_blank_other_monitors (XAppMonitorBlanker *self,
  75. GtkWindow *window)
  76. {
  77. GdkScreen *screen;
  78. int active_monitor;
  79. int i;
  80. g_return_if_fail (XAPP_IS_MONITOR_BLANKER (self));
  81. if (self->priv->windows != NULL)
  82. return;
  83. screen = gtk_window_get_screen (window);
  84. active_monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET (window)));
  85. self->priv->num_outputs = gdk_screen_get_n_monitors (screen);
  86. self->priv->windows = g_new (GtkWidget *, self->priv->num_outputs);
  87. for (i = 0; i < self->priv->num_outputs; i++)
  88. {
  89. if (i != active_monitor)
  90. {
  91. self->priv->windows[i] = create_blanking_window (screen, i);
  92. }
  93. else
  94. {
  95. // initialize at NULL so it gets properly skipped when windows get destroyed
  96. self->priv->windows[i] = NULL;
  97. }
  98. }
  99. self->priv->blanked = TRUE;
  100. }
  101. void
  102. xapp_monitor_blanker_unblank_monitors (XAppMonitorBlanker *self)
  103. {
  104. int i;
  105. g_return_if_fail (XAPP_IS_MONITOR_BLANKER (self));
  106. if (self->priv->windows == NULL)
  107. return;
  108. for (i = 0; i < self->priv->num_outputs; i++)
  109. {
  110. if (self->priv->windows[i] != NULL)
  111. {
  112. gtk_widget_destroy (self->priv->windows[i]);
  113. self->priv->windows[i] = NULL;
  114. }
  115. }
  116. g_free (self->priv->windows);
  117. self->priv->windows = NULL;
  118. self->priv->blanked = FALSE;
  119. }
  120. gboolean
  121. xapp_monitor_blanker_are_monitors_blanked (XAppMonitorBlanker *self)
  122. {
  123. return self->priv->blanked;
  124. }