Hello!

    I've got extra monitor on work so could test PCManFM with TwinView.
The TwinView is cool but I've found PCManFM impossible to handle it at
all - it thinks my monitor is 3840x1080 so works appropriately which was
too unadequate - starting from wallpapers and ending that all windows
could be opened only on first monitor. Some digging helped and all works
fine now. Patch attached, it will be in next release. It may be not fully
free of bugs so I would like everyone with two (or more) monitors to test
it. Thank you. :)

    With the best wishes.
    Andriy.
--- pcmanfm-1.0~rc1.orig/src/pcmanfm.c
+++ pcmanfm-1.0~rc1/src/pcmanfm.c
@@ -292,14 +292,14 @@ gboolean pcmanfm_run()
         else if(show_pref > 0)
         {
             /* FIXME: pass screen number from client */
-            fm_edit_preference(GTK_WINDOW(fm_desktop_get(0)), show_pref - 1);
+            fm_edit_preference(GTK_WINDOW(fm_desktop_get(0, 0)), show_pref - 1);
             show_pref = 0;
             return TRUE;
         }
         else if(desktop_pref)
         {
             /* FIXME: pass screen number from client */
-            fm_desktop_preference(NULL, GTK_WINDOW(fm_desktop_get(0)));
+            fm_desktop_preference(NULL, GTK_WINDOW(fm_desktop_get(0, 0)));
             desktop_pref = FALSE;
             return TRUE;
         }
--- pcmanfm-1.0~rc1.orig/src/desktop.h
+++ pcmanfm-1.0~rc1/src/desktop.h
@@ -79,7 +79,8 @@ struct _FmDesktop
     FmFolderModel* model;
     FmBackgroundCache* wallpapers;
     GtkMenu* popup;
-    uint cur_desktop;
+    guint cur_desktop;
+    gint monitor;
 };
 
 struct _FmDesktopClass
@@ -92,9 +93,9 @@ FmFileInfoList* fm_desktop_dup_selected_
 FmPathList* fm_desktop_dup_selected_paths(FmDesktop* desktop);
 
 GType       fm_desktop_get_type     (void);
-FmDesktop*  fm_desktop_new          (void);
+FmDesktop*  fm_desktop_new          (GdkScreen* screen, guint monitor);
 
-FmDesktop*  fm_desktop_get          (guint screen);
+FmDesktop*  fm_desktop_get          (guint screen, guint monitor);
 
 void fm_desktop_manager_init();
 void fm_desktop_manager_finalize();
--- pcmanfm-1.0~rc1.orig/src/desktop.c
+++ pcmanfm-1.0~rc1/src/desktop.c
@@ -169,6 +169,15 @@ GtkTargetEntry dnd_targets[] =
     {"application/x-desktop-item", GTK_TARGET_SAME_WIDGET, FM_DND_DEST_DESKTOP_ITEM}
 };
 
+enum
+{
+    PROP_0,
+    PROP_MONITOR,
+    N_PROPERTIES
+};
+
+static GParamSpec *fm_desktop_properties[N_PROPERTIES] = { NULL, };
+
 /* insert GtkUIManager XML definitions */
 #include "desktop-ui.c"
 
@@ -339,15 +348,33 @@ static void fm_desktop_destroy(GtkObject
 
 static void fm_desktop_init(FmDesktop *self)
 {
+}
+
+/* we should have a constructor to handle parameters */
+static GObject* fm_desktop_constructor(GType type, guint n_construct_properties,
+                                       GObjectConstructParam *construct_properties)
+{
+    GObject* object = G_OBJECT_CLASS(fm_desktop_parent_class)->constructor(type, n_construct_properties, construct_properties);
+    FmDesktop* self = (FmDesktop*)object;
     GdkScreen* screen = gtk_widget_get_screen((GtkWidget*)self);
     GdkWindow* root;
     //PangoContext* pc;
     GtkTargetList* targets;
     GtkUIManager* ui;
     GtkActionGroup* act_grp;
+    guint i;
+    GdkRectangle geom;
 
-    gtk_window_set_default_size((GtkWindow*)self, gdk_screen_get_width(screen), gdk_screen_get_height(screen));
-    gtk_window_move(GTK_WINDOW(self), 0, 0);
+    for(i = 0; i < n_construct_properties; i++)
+        if(!strcmp(construct_properties[i].pspec->name, "monitor")
+           && G_VALUE_HOLDS_INT(construct_properties[i].value))
+            self->monitor = g_value_get_int(construct_properties[i].value);
+    g_debug("fm_desktop_constructor for monitor %d", self->monitor);
+    gdk_screen_get_monitor_geometry(screen, self->monitor, &geom);
+    gtk_window_set_default_size((GtkWindow*)self, geom.width, geom.height);
+    //gtk_window_set_default_size((GtkWindow*)self, gdk_screen_get_width(screen), gdk_screen_get_height(screen));
+    gtk_window_move(GTK_WINDOW(self), geom.x, geom.y);
+    //gtk_window_move(GTK_WINDOW(self), 0, 0);
     gtk_widget_set_app_paintable((GtkWidget*)self, TRUE);
     gtk_window_set_type_hint(GTK_WINDOW(self), GDK_WINDOW_TYPE_HINT_DESKTOP);
     gtk_widget_add_events((GtkWidget*)self,
@@ -426,12 +453,14 @@ static void fm_desktop_init(FmDesktop *s
 
     g_object_unref(act_grp);
     g_object_unref(ui);
+    return object;
 }
 
 
-FmDesktop *fm_desktop_new(void)
+FmDesktop *fm_desktop_new(GdkScreen* screen, guint monitor)
 {
-    return g_object_new(FM_TYPE_DESKTOP, NULL);
+    return g_object_new(FM_TYPE_DESKTOP, "screen", screen, "monitor", monitor, NULL);
+    //return g_object_new(FM_TYPE_DESKTOP, NULL);
 }
 
 static char* get_config_file(FmDesktop* desktop, gboolean create_dir)
@@ -521,7 +550,7 @@ static FmJobErrorAction on_folder_error(
 void fm_desktop_manager_init()
 {
     GdkDisplay * gdpy;
-    guint i;
+    guint i, n_scr, n_mon, scr, mon;
     const char* desktop_path;
 
     if(! win_group)
@@ -546,15 +575,23 @@ void fm_desktop_manager_init()
         font_desc = pango_font_description_from_string(app_config->desktop_font);
 
     gdpy = gdk_display_get_default();
-    n_screens = gdk_display_get_n_screens(gdpy);
+    n_scr = gdk_display_get_n_screens(gdpy);
+    n_screens = 0;
+    for(i = 0; i < n_scr; i++)
+        n_screens += gdk_screen_get_n_monitors(gdk_display_get_screen(gdpy, i));
     desktops = g_new(FmDesktop*, n_screens);
-    for(i = 0; i < n_screens; i++)
+    for(scr = 0, i = 0; scr < n_scr; scr++)
     {
-        GtkWidget* desktop = (GtkWidget*)fm_desktop_new();
-        desktops[i] = (FmDesktop*)desktop;
-        gtk_widget_realize(desktop);  /* without this, setting wallpaper won't work */
-        gtk_widget_show_all(desktop);
-        gdk_window_lower(gtk_widget_get_window(desktop));
+        GdkScreen* screen = gdk_display_get_screen(gdpy, scr);
+        n_mon = gdk_screen_get_n_monitors(screen);
+        for(mon = 0; mon < n_mon; mon++)
+        {
+            GtkWidget* desktop = (GtkWidget*)fm_desktop_new(screen, mon);
+            desktops[i++] = (FmDesktop*)desktop;
+            gtk_widget_realize(desktop);  /* without this, setting wallpaper won't work */
+            gtk_widget_show_all(desktop);
+            gdk_window_lower(gtk_widget_get_window(desktop));
+        }
     }
 
     wallpaper_changed = g_signal_connect(app_config, "changed::wallpaper", G_CALLBACK(on_wallpaper_changed), NULL);
@@ -1160,7 +1197,6 @@ static gboolean on_key_press(GtkWidget*
             fm_path_list_unref(sels);
         }
         break;
-    /* TODO: GDK_F11 to go fullscreen? */
     }
     return GTK_WIDGET_CLASS(fm_desktop_parent_class)->key_press_event(w, evt);
 }
@@ -1310,8 +1346,11 @@ static void on_size_allocate(GtkWidget*
 static void on_size_request(GtkWidget* w, GtkRequisition* req)
 {
     GdkScreen* scr = gtk_widget_get_screen(w);
-    req->width = gdk_screen_get_width(scr);
-    req->height = gdk_screen_get_height(scr);
+    gint monitor = FM_DESKTOP(w)->monitor;
+    GdkRectangle geom;
+    gdk_screen_get_monitor_geometry(scr, monitor, &geom);
+    req->width = geom.width;
+    req->height = geom.height;
 }
 
 static gboolean is_point_in_rect(GdkRectangle* rect, int x, int y)
@@ -1974,8 +2013,10 @@ static void update_background(FmDesktop*
         else
         {
             GdkScreen* screen = gtk_widget_get_screen(widget);
-            dest_w = gdk_screen_get_width(screen);
-            dest_h = gdk_screen_get_height(screen);
+            GdkRectangle geom;
+            gdk_screen_get_monitor_geometry(screen, desktop->monitor, &geom);
+            dest_w = geom.width;
+            dest_h = geom.height;
             pixmap = gdk_pixmap_new(window, dest_w, dest_h, -1);
         }
 
@@ -2098,10 +2139,8 @@ static void update_working_area(FmDeskto
     gulong* working_area;
 
     /* default to screen size */
-    desktop->working_area.x = 0;
-    desktop->working_area.y = 0;
-    desktop->working_area.width = gdk_screen_get_width(screen);
-    desktop->working_area.height = gdk_screen_get_height(screen);
+    /* FIXME: for GTK3 it's gdk_screen_get_monitor_workarea() */
+    gdk_screen_get_monitor_geometry(screen, desktop->monitor, &desktop->working_area);
 
     if(XGetWindowProperty(GDK_WINDOW_XDISPLAY(root), GDK_WINDOW_XID(root),
                        XA_NET_NUMBER_OF_DESKTOPS, 0, 1, False, XA_CARDINAL, &ret_type,
@@ -2137,6 +2176,8 @@ static void update_working_area(FmDeskto
     desktop->working_area.y = (gint)working_area[1];
     desktop->working_area.width = (gint)working_area[2];
     desktop->working_area.height = (gint)working_area[3];
+    g_debug("got working area: %d.%d.%d.%d", desktop->working_area.x, desktop->working_area.y,
+            desktop->working_area.width, desktop->working_area.height);
 
     XFree(prop);
 _out:
@@ -2146,7 +2187,9 @@ _out:
 
 static void on_screen_size_changed(GdkScreen* screen, FmDesktop* desktop)
 {
-    gtk_window_resize((GtkWindow*)desktop, gdk_screen_get_width(screen), gdk_screen_get_height(screen));
+    GdkRectangle geom;
+    gdk_screen_get_monitor_geometry(screen, desktop->monitor, &geom);
+    gtk_window_resize((GtkWindow*)desktop, geom.width, geom.height);
 }
 
 static void on_dnd_src_data_get(FmDndSrc* ds, FmDesktop* desktop)
@@ -2790,17 +2833,44 @@ static void on_drag_data_get(GtkWidget *
 }
 
 
-FmDesktop* fm_desktop_get(guint screen)
+FmDesktop* fm_desktop_get(guint screen, guint monitor)
 {
     return (screen < n_screens) ? desktops[screen] : NULL;
 }
 
+static void fm_desktop_set_property(GObject *object, guint property_id,
+                                    const GValue *value, GParamSpec *pspec)
+{
+    switch(property_id)
+    {
+        case PROP_MONITOR:
+            FM_DESKTOP(object)->monitor = g_value_get_int(value);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+    }
+}
+
+static void fm_desktop_get_property(GObject *object, guint property_id,
+                                    GValue *value, GParamSpec *pspec)
+{
+    switch(property_id)
+    {
+        case PROP_MONITOR:
+            g_value_set_int(value, FM_DESKTOP(object)->monitor);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+    }
+}
+
 static void fm_desktop_class_init(FmDesktopClass *klass)
 {
     GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
     typedef gboolean (*DeleteEvtHandler) (GtkWidget*, GdkEventAny*);
     char* atom_names[] = {"_NET_WORKAREA", "_NET_NUMBER_OF_DESKTOPS", "_NET_CURRENT_DESKTOP", "_XROOTMAP_ID"};
     Atom atoms[G_N_ELEMENTS(atom_names)] = {0};
+    GObjectClass* object_class = G_OBJECT_CLASS(klass);
 
 #if GTK_CHECK_VERSION(3, 0, 0)
     widget_class->destroy = fm_desktop_destroy;
@@ -2837,4 +2907,15 @@ static void fm_desktop_class_init(FmDesk
         XA_NET_CURRENT_DESKTOP = atoms[2];
         XA_XROOTMAP_ID= atoms[3];
     }
+
+    object_class->constructor = fm_desktop_constructor;
+    object_class->set_property = fm_desktop_set_property;
+    object_class->get_property = fm_desktop_get_property;
+
+    fm_desktop_properties[PROP_MONITOR] =
+        g_param_spec_int("monitor", "Monitor",
+                         "Monitor number where desktop is",
+                         0, 127, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
+    g_object_class_install_properties(object_class, N_PROPERTIES,
+                                      fm_desktop_properties);
 }
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Pcmanfm-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pcmanfm-develop

Reply via email to