From http://www.jwz.org/xscreensaver/xscreensaver-5.40.tar.gz
[xscreensaver] / OSX / grabclient-osx.m
index a0a949d7f14b9053cd2ac1b0271ece4c2d9bf902..7bfdcb4fa811b0e921dbd585f571b2422e4e39c2 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992-2016 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2018 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -286,6 +286,8 @@ osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
          use it if when being compiled against the 10.5 SDK or later.
        */
 
+extern float jwxyz_scale (Window);  /* jwxyzI.h */
+
 /* Loads an image into the Drawable, returning once the image is loaded.
  */
 Bool
@@ -307,10 +309,11 @@ osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
   // Grab only the rectangle of the screen underlying this window.
   //
   CGRect cgrect;
+  double s = jwxyz_scale (xwindow);
   cgrect.origin.x    = window_x;
   cgrect.origin.y    = window_y;
-  cgrect.size.width  = xgwa.width;
-  cgrect.size.height = xgwa.height;
+  cgrect.size.width  = xgwa.width  / s;
+  cgrect.size.height = xgwa.height / s;
 
   /* If a password is required to unlock the screen, a large black
      window will be on top of all of the desktop windows by the time
@@ -322,31 +325,25 @@ osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
      Oct 2016: Surprise, this trick no longer works on MacOS 10.12.  Sigh.
    */
 
-  // save our current level so we can restore it later
-  int oldLevel = [[nsview window] level]; 
+  CGWindowID windowNumber = (CGWindowID) nsview.window.windowNumber;
 
-# if 0
   {
-    FILE *f = fopen("/tmp/log.txt", "w");
     CFArrayRef L = CGWindowListCopyWindowInfo (kCGWindowListOptionOnScreenOnly,
                                                kCGNullWindowID);
 
-    fprintf(f, "# %d\n", [[nsview window] windowNumber]);
-
-    int n = CFArrayGetCount(L);
+    CFIndex n = CFArrayGetCount(L);
     for (int i = 0; i < n; i++) {
       NSDictionary *dict = (NSDictionary *) CFArrayGetValueAtIndex(L, i);
-      fprintf(f,
-              "%d \"%s\"\n",
-              (int) [dict objectForKey:kCGWindowNumber],
-              [(NSString *) [dict objectForKey:kCGWindowOwnerName]
-                cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+
+      // loginwindow creates multiple toplevel windows. Grab the lowest one.
+      if(![([dict objectForKey:(NSString *)kCGWindowOwnerName])
+           compare:@"loginwindow"]) {
+        windowNumber = ((NSNumber *)[dict objectForKey:
+                                     (NSString *)kCGWindowNumber]).intValue;
+      }
     }
-    fclose(f);
+    CFRelease (L);
   }
-#endif
-
-  [[nsview window] setLevel:CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey)];
 
   // Grab a screen shot of those windows below this one
   // (hey, X11 can't do that!)
@@ -354,12 +351,9 @@ osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
   CGImageRef img = 
     CGWindowListCreateImage (cgrect,
                              kCGWindowListOptionOnScreenBelowWindow,
-                             [[nsview window] windowNumber],
+                             windowNumber,
                              kCGWindowImageDefault);
 
-  // put us back above the login windows so the screensaver is visible.
-  [[nsview window] setLevel:oldLevel];
-
   if (! img) return False;
 
   // Render the grabbed CGImage into the Drawable.