summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nautilus-desktop/nautilus-desktop-canvas-view.c97
-rw-r--r--nautilus-desktop/nautilus-desktop-window.c227
2 files changed, 214 insertions, 110 deletions
diff --git a/nautilus-desktop/nautilus-desktop-canvas-view.c b/nautilus-desktop/nautilus-desktop-canvas-view.c
index 1bb505253..830dc26f9 100644
--- a/nautilus-desktop/nautilus-desktop-canvas-view.c
+++ b/nautilus-desktop/nautilus-desktop-canvas-view.c
@@ -59,11 +59,6 @@
#include <sys/types.h>
#include <unistd.h>
-struct NautilusDesktopCanvasViewDetails
-{
- GdkWindow *root_window;
-};
-
static void default_zoom_level_changed (gpointer user_data);
static void real_update_context_menus (NautilusFilesView *view);
static char* real_get_backing_uri (NautilusFilesView *view);
@@ -86,31 +81,31 @@ canvas_container_set_workarea (NautilusCanvasContainer *canvas_container,
int n_items)
{
int left, right, top, bottom;
- int screen_width, screen_height;
int i;
+ GdkRectangle geometry;
left = right = top = bottom = 0;
-
- screen_width = gdk_screen_get_width (screen);
- screen_height = gdk_screen_get_height (screen);
+ gdk_screen_get_monitor_geometry (screen, gdk_screen_get_primary_monitor (screen), &geometry);
for (i = 0; i < n_items; i += 4) {
- int x = workareas [i];
- int y = workareas [i + 1];
- int width = workareas [i + 2];
- int height = workareas [i + 3];
+ GdkRectangle workarea;
- if ((x + width) > screen_width || (y + height) > screen_height)
+ workarea.x = workareas[i];
+ workarea.y = workareas[i + 1];
+ workarea.width = workareas[i + 2];
+ workarea.height = workareas[i + 3];
+
+ if (!gdk_rectangle_intersect (&geometry, &workarea, &workarea))
continue;
- left = MAX (left, x);
- right = MAX (right, screen_width - width - x);
- top = MAX (top, y);
- bottom = MAX (bottom, screen_height - height - y);
+ left = MAX (left, workarea.x);
+ right = MAX (right, (workarea.x + workarea.width) - (geometry.x + geometry.width));
+ top = MAX (top, workarea.y);
+ bottom = MAX (bottom, (workarea.y + workarea.height) - (geometry.y + geometry.height));
}
nautilus_canvas_container_set_margins (canvas_container,
- left, right, top, bottom);
+ 0, 0, 0, 0);
}
static void
@@ -196,28 +191,6 @@ net_workarea_changed (NautilusDesktopCanvasView *canvas_view,
g_free (workareas);
}
-static GdkFilterReturn
-desktop_canvas_view_property_filter (GdkXEvent *gdk_xevent,
- GdkEvent *event,
- gpointer data)
-{
- XEvent *xevent = gdk_xevent;
- NautilusDesktopCanvasView *canvas_view;
-
- canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (data);
-
- switch (xevent->type) {
- case PropertyNotify:
- if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_WORKAREA"))
- net_workarea_changed (canvas_view, event->any.window);
- break;
- default:
- break;
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
static guint
real_get_id (NautilusFilesView *view)
{
@@ -305,43 +278,6 @@ nautilus_desktop_canvas_view_class_init (NautilusDesktopCanvasViewClass *class)
vclass->end_loading = nautilus_desktop_canvas_view_end_loading;
vclass->get_backing_uri = real_get_backing_uri;
vclass->check_empty_states = real_check_empty_states;
-
- g_type_class_add_private (class, sizeof (NautilusDesktopCanvasViewDetails));
-}
-
-static void
-unrealized_callback (GtkWidget *widget, NautilusDesktopCanvasView *desktop_canvas_view)
-{
- g_return_if_fail (desktop_canvas_view->details->root_window != NULL);
-
- /* Remove the property filter */
- gdk_window_remove_filter (desktop_canvas_view->details->root_window,
- desktop_canvas_view_property_filter,
- desktop_canvas_view);
- desktop_canvas_view->details->root_window = NULL;
-}
-
-static void
-realized_callback (GtkWidget *widget, NautilusDesktopCanvasView *desktop_canvas_view)
-{
- GdkWindow *root_window;
- GdkScreen *screen;
-
- g_return_if_fail (desktop_canvas_view->details->root_window == NULL);
-
- screen = gtk_widget_get_screen (widget);
- root_window = gdk_screen_get_root_window (screen);
-
- desktop_canvas_view->details->root_window = root_window;
-
- /* Read out the workarea geometry and update the icon container accordingly */
- net_workarea_changed (desktop_canvas_view, root_window);
-
- /* Setup the property filter */
- gdk_window_set_events (root_window, GDK_PROPERTY_CHANGE_MASK);
- gdk_window_add_filter (root_window,
- desktop_canvas_view_property_filter,
- desktop_canvas_view);
}
static void
@@ -696,11 +632,6 @@ nautilus_desktop_canvas_view_init (NautilusDesktopCanvasView *desktop_canvas_vie
g_signal_connect_object (canvas_container, "realize",
G_CALLBACK (desktop_canvas_container_realize), desktop_canvas_view, 0);
- g_signal_connect_object (desktop_canvas_view, "realize",
- G_CALLBACK (realized_callback), desktop_canvas_view, 0);
- g_signal_connect_object (desktop_canvas_view, "unrealize",
- G_CALLBACK (unrealized_callback), desktop_canvas_view, 0);
-
g_signal_connect_swapped (nautilus_icon_view_preferences,
"changed::" NAUTILUS_PREFERENCES_ICON_VIEW_DEFAULT_ZOOM_LEVEL,
G_CALLBACK (default_zoom_level_changed),
diff --git a/nautilus-desktop/nautilus-desktop-window.c b/nautilus-desktop/nautilus-desktop-window.c
index 7c3abecb6..81392d658 100644
--- a/nautilus-desktop/nautilus-desktop-window.c
+++ b/nautilus-desktop/nautilus-desktop-window.c
@@ -45,6 +45,7 @@ struct NautilusDesktopWindowDetails {
gboolean loaded;
GtkWidget *desktop_selection;
+ GdkWindow *root_window;
};
G_DEFINE_TYPE (NautilusDesktopWindow, nautilus_desktop_window,
@@ -166,6 +167,142 @@ nautilus_desktop_window_init_selection (NautilusDesktopWindow *window)
window->details->desktop_selection = selection_widget;
}
+static GdkRectangle*
+intersect_primary_monitor_with_workareas (NautilusDesktopWindow *window,
+ long *workareas,
+ int n_items)
+{
+ int i;
+ GdkRectangle geometry;
+ GdkRectangle *intersected_geometry;
+
+ intersected_geometry = g_new (GdkRectangle, 1);
+ gdk_screen_get_monitor_geometry (gdk_screen_get_default (),
+ gdk_screen_get_primary_monitor (gdk_screen_get_default ()),
+ &geometry);
+ intersected_geometry->x = geometry.x;
+ intersected_geometry->y = geometry.y;
+ intersected_geometry->width = geometry.width;
+ intersected_geometry->height = geometry.height;
+
+ for (i = 0; i < n_items; i += 4) {
+ GdkRectangle workarea;
+
+ workarea.x = workareas[i];
+ workarea.y = workareas[i + 1];
+ workarea.width = workareas[i + 2];
+ workarea.height = workareas[i + 3];
+
+ g_print ("owrkarea %d %d %d %d, intersected %d %d %d %d\n", workarea.x, workarea.y, workarea.width, workarea.height, intersected_geometry->x, intersected_geometry->y,
+ intersected_geometry->width, intersected_geometry->height);
+ if (!gdk_rectangle_intersect (&geometry, &workarea, &workarea))
+ continue;
+
+ intersected_geometry->x = MAX (intersected_geometry->x, workarea.x);
+ intersected_geometry->y = MAX (intersected_geometry->y, workarea.y);
+ intersected_geometry->width = MIN (intersected_geometry->width,
+ workarea.x + workarea.width - intersected_geometry->x);
+ intersected_geometry->height = MIN (intersected_geometry->height,
+ workarea.y + workarea.height - intersected_geometry->y);
+ }
+
+ return intersected_geometry;
+}
+
+static GdkRectangle*
+calculate_size_desktop_geometry (NautilusDesktopWindow *window)
+{
+ long *nworkareas = NULL;
+ long *workareas = NULL;
+ GdkAtom type_returned;
+ int format_returned;
+ int length_returned;
+ GdkWindow *root_window;
+ GdkRectangle *intersected_geometry = NULL;
+
+ g_print ("calculate size desktop\n");
+ root_window = gdk_screen_get_root_window (gdk_screen_get_default ());
+ /* Find the number of desktops so we know how long the
+ * workareas array is going to be (each desktop will have four
+ * elements in the workareas array describing
+ * x,y,width,height) */
+ gdk_error_trap_push ();
+ if (!gdk_property_get (root_window,
+ gdk_atom_intern ("_NET_NUMBER_OF_DESKTOPS", FALSE),
+ gdk_x11_xatom_to_atom (XA_CARDINAL),
+ 0, 4, FALSE,
+ &type_returned,
+ &format_returned,
+ &length_returned,
+ (guchar **) &nworkareas)) {
+ g_warning("Can not calculate _NET_NUMBER_OF_DESKTOPS");
+ }
+ if (gdk_error_trap_pop()
+ || nworkareas == NULL
+ || type_returned != gdk_x11_xatom_to_atom (XA_CARDINAL)
+ || format_returned != 32)
+ g_warning("Can not calculate _NET_NUMBER_OF_DESKTOPS");
+
+ /* Note : gdk_property_get() is broken (API documents admit
+ * this). As a length argument, it expects the number of
+ * _bytes_ of data you require. Internally, gdk_property_get
+ * converts that value to a count of 32 bit (4 byte) elements.
+ * However, the length returned is in bytes, but is calculated
+ * via the count of returned elements * sizeof(long). This
+ * means on a 64 bit system, the number of bytes you have to
+ * request does not correspond to the number of bytes you get
+ * back, and is the reason for the workaround below.
+ */
+ gdk_error_trap_push ();
+ if (nworkareas == NULL || (*nworkareas < 1)
+ || !gdk_property_get (root_window,
+ gdk_atom_intern ("_NET_WORKAREA", FALSE),
+ gdk_x11_xatom_to_atom (XA_CARDINAL),
+ 0, ((*nworkareas) * 4 * 4), FALSE,
+ &type_returned,
+ &format_returned,
+ &length_returned,
+ (guchar **) &workareas)) {
+ g_warning("Can not get _NET_WORKAREA");
+ workareas = NULL;
+ }
+
+ if (gdk_error_trap_pop ()
+ || workareas == NULL
+ || type_returned != gdk_x11_xatom_to_atom (XA_CARDINAL)
+ || ((*nworkareas) * 4 * sizeof(long)) != length_returned
+ || format_returned != 32) {
+ g_critical ("NET_WORKAREA canot be peeked");
+ } else {
+ g_print ("good good \n");
+ intersected_geometry = intersect_primary_monitor_with_workareas (window, workareas, *nworkareas);
+ }
+
+ if (nworkareas != NULL)
+ g_free (nworkareas);
+
+ if (workareas != NULL)
+ g_free (workareas);
+
+ return intersected_geometry;
+}
+
+static void
+net_workarea_changed (NautilusDesktopWindow *window)
+{
+ GdkRectangle *geometry;
+
+ geometry = calculate_size_desktop_geometry (window);
+ g_object_set (window,
+ "width_request", geometry->width,
+ "height_request", geometry->height,
+ NULL);
+
+ gtk_window_move (GTK_WINDOW (window), geometry->x, geometry->y);
+
+ g_free (geometry);
+}
+
static void
nautilus_desktop_window_constructed (GObject *obj)
{
@@ -185,11 +322,11 @@ nautilus_desktop_window_constructed (GObject *obj)
gtk_window_set_decorated (GTK_WINDOW (window),
FALSE);
- gtk_window_move (GTK_WINDOW (window), 0, 0);
-
- g_object_set_data (G_OBJECT (window), "is_desktop_window",
+ g_object_set_data (G_OBJECT (window), "is_desktop_window",
GINT_TO_POINTER (1));
+ net_workarea_changed (window);
+
nautilus_desktop_window_init_selection (window);
nautilus_desktop_window_init_actions (window);
@@ -218,6 +355,58 @@ nautilus_desktop_window_constructed (GObject *obj)
}
}
+static GdkFilterReturn
+root_window_property_filter (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *xevent = gdk_xevent;
+ NautilusDesktopWindow *window;
+
+ window = NAUTILUS_DESKTOP_WINDOW (data);
+
+ switch (xevent->type) {
+ case PropertyNotify:
+ if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_WORKAREA"))
+ net_workarea_changed (window);
+ break;
+ default:
+ break;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+
+static void
+unrealized_callback (GtkWidget *widget,
+ NautilusDesktopWindow *window)
+{
+ /* Remove the property filter */
+ gdk_window_remove_filter (gdk_screen_get_root_window (gdk_screen_get_default ()),
+ root_window_property_filter,
+ window);
+}
+
+static void
+realized_callback (GtkWidget *widget, NautilusDesktopWindow *window)
+{
+ GdkWindow *root_window;
+ GdkScreen *screen;
+
+ screen = gtk_widget_get_screen (widget);
+ root_window = gdk_screen_get_root_window (screen);
+
+ /* Read out the workarea geometry and update the icon container accordingly */
+ net_workarea_changed (window);
+
+ /* Setup the property filter */
+ gdk_window_set_events (root_window, GDK_PROPERTY_CHANGE_MASK);
+ gdk_window_add_filter (root_window,
+ root_window_property_filter,
+ window);
+}
+
static void
nautilus_desktop_window_init (NautilusDesktopWindow *window)
{
@@ -226,43 +415,27 @@ nautilus_desktop_window_init (NautilusDesktopWindow *window)
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)),
"nautilus-desktop-window");
-}
+ g_signal_connect_object (window, "realize",
+ G_CALLBACK (realized_callback), window, 0);
+ g_signal_connect_object (window, "unrealize",
+ G_CALLBACK (unrealized_callback), window, 0);
-static void
-nautilus_desktop_window_screen_size_changed (GdkScreen *screen,
- NautilusDesktopWindow *window)
-{
- int width_request, height_request;
-
- width_request = gdk_screen_get_width (screen);
- height_request = gdk_screen_get_height (screen);
-
- g_object_set (window,
- "width_request", width_request,
- "height_request", height_request,
- NULL);
}
static NautilusDesktopWindow *
nautilus_desktop_window_new (void)
{
- GdkScreen *screen;
GApplication *application;
NautilusDesktopWindow *window;
- int width_request, height_request;
application = g_application_get_default ();
- screen = gdk_screen_get_default ();
- width_request = gdk_screen_get_width (screen);
- height_request = gdk_screen_get_height (screen);
-
window = g_object_new (NAUTILUS_TYPE_DESKTOP_WINDOW,
"application", application,
"disable-chrome", TRUE,
- "width_request", width_request,
- "height_request", height_request,
NULL);
+ net_workarea_changed (window);
+
return window;
}
@@ -361,8 +534,8 @@ realize (GtkWidget *widget)
set_wmspec_desktop_hint (gtk_widget_get_window (widget));
details->size_changed_id =
- g_signal_connect (gtk_window_get_screen (GTK_WINDOW (window)), "size-changed",
- G_CALLBACK (nautilus_desktop_window_screen_size_changed), window);
+ g_signal_connect_swapped (gtk_window_get_screen (GTK_WINDOW (window)), "size-changed",
+ G_CALLBACK (net_workarea_changed), window);
}
static void