Unfortunately, this is not possible because of how the PIL gets the dimensions of the display device. When it receives the device context, it receives one for all connected monitors:
screen = CreateDC("DISPLAY", NULL, NULL, NULL);
( display.c , line 296, version 1.1.7)
However, to get the dimensions of the display, it uses this code:
width = GetDeviceCaps(screen, HORZRES); height = GetDeviceCaps(screen, VERTRES);
( display.c , lines 299-300, version 1.1.7)
Returns only the dimensions of the main, active monitor. All subsequent operations are performed with these widths and heights, resulting in a final image that is only the size of the main display.
To get a pop-up window of all connected monitors, these two lines must be replaced with something like:
width = GetSystemMetrics(SM_CXVIRTUALSCREEN); height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
After that, you will need to recompile the PIL. This will give you the dimensions of the virtual screen, which is the "... bounding box of all display monitors." [ MSDN ]
A more correct implementation would be to use EnumDisplayMonitors to obtain device contexts for individual monitors, as well as change the ImageGrab.grab () interface (or add a new function) to allow the selection of a specific monitor whose device context will be used for other operations.