diff options
Diffstat (limited to 'nautilus-desktop')
-rw-r--r-- | nautilus-desktop/nautilus-desktop-canvas-view.c | 97 | ||||
-rw-r--r-- | nautilus-desktop/nautilus-desktop-window.c | 227 |
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 |