@@ -4510,7 +4510,74 @@ - (void) freecursor: (void*) cid
45104510
45114511 return scrSize;
45124512}
4513-
4513+
4514+ /* Gets the work areas (if the window manager supports _NET_WORKAREA) of the
4515+ * monitors/screens for the display. These are supposed to be the extents of
4516+ * the screen that we can use without trspassing on areas reservced for the
4517+ * window manager.
4518+ */
4519+ static NSArray *
4520+ _workAreas (Display *dpy, Window root)
4521+ {
4522+ Atom workarea_atom;
4523+ Atom type;
4524+ int format;
4525+ int status;
4526+ unsigned long *items;
4527+ unsigned long nitems;
4528+ unsigned long bytes_after;
4529+ unsigned char *data = NULL ;
4530+ unsigned count;
4531+ unsigned index;
4532+ NSMutableArray *array;
4533+
4534+ workarea_atom = XInternAtom (dpy, " _NET_WORKAREA" , False);
4535+ status = XGetWindowProperty (dpy, root, workarea_atom,
4536+ 0 , /* offset */
4537+ (~0L ), /* read all items */
4538+ False,
4539+ XA_CARDINAL,
4540+ &type,
4541+ &format,
4542+ &nitems,
4543+ &bytes_after,
4544+ &data
4545+ );
4546+
4547+ if (status != Success || !data)
4548+ {
4549+ NSLog (@" Failed to get _NET_WORKAREA\n " );
4550+ return nil ;
4551+ }
4552+ if (format != 32 )
4553+ {
4554+ XFree (data);
4555+ return nil ;
4556+ }
4557+
4558+ items = (unsigned long *)data;
4559+ count = nitems / 4 ;
4560+ array = [NSMutableArray arrayWithCapacity: count];
4561+ for (index = 0 ; index < count; index++)
4562+ {
4563+ NSRect frame;
4564+
4565+ frame.origin .x = (uint32_t )*items++;
4566+ frame.origin .y = (uint32_t )*items++;
4567+ frame.size .width = (uint32_t )*items++;
4568+ frame.size .height = (uint32_t )*items++;
4569+ // X coordinates need to be flipped to OpenStep coordinates
4570+ if (frame.origin .y > 0.0 )
4571+ {
4572+ frame.size .height -= frame.origin .y ;
4573+ frame.origin .y = 0.0 ;
4574+ }
4575+ [array addObject: [NSValue valueWithRect: frame]];
4576+ }
4577+ XFree (data);
4578+ return array;
4579+ }
4580+
45144581
45154582/* This method assumes that we deal with one X11 screen - `defScreen`.
45164583 Basically it means that we have DISPLAY variable set to `:0.0`.
@@ -4524,16 +4591,18 @@ - (void) freecursor: (void*) cid
45244591 We map XRandR monitors (outputs) to NSScreen. */
45254592- (NSArray *)screenList
45264593{
4594+ Window root = [self xDisplayRootWindow ];
4595+ NSArray *workAreas = _workAreas (dpy, root);
45274596 xScreenSize = _screenSize (dpy, defScreen);
45284597
45294598 monitorsCount = 0 ;
4530- if (monitors != NULL ) {
4531- NSZoneFree ([self zone ], monitors);
4532- monitors = NULL ;
4533- }
4599+ if (monitors != NULL )
4600+ {
4601+ NSZoneFree ([self zone ], monitors);
4602+ monitors = NULL ;
4603+ }
45344604
45354605#ifdef HAVE_XRANDR
4536- Window root = [self xDisplayRootWindow ];
45374606 XRRScreenResources *screen_res = XRRGetScreenResources (dpy, root);
45384607
45394608 if (screen_res != NULL )
@@ -4543,38 +4612,58 @@ - (NSArray *)screenList
45434612 {
45444613 int i;
45454614 int mi;
4546- NSMutableArray *tmpScreens = [ NSMutableArray arrayWithCapacity: monitorsCount] ;
4615+ NSMutableArray *tmpScreens;
45474616 RROutput primary_output = XRRGetOutputPrimary (dpy, root);
45484617
4549- monitors = NSZoneMalloc ([self zone ], monitorsCount * sizeof (MonitorDevice));
4618+ tmpScreens = [NSMutableArray arrayWithCapacity: monitorsCount];
4619+
4620+ monitors = NSZoneMalloc ([self zone ],
4621+ monitorsCount * sizeof (MonitorDevice));
45504622
45514623 for (i = 0 , mi = 0 ; i < screen_res->noutput ; i++)
45524624 {
45534625 XRROutputInfo *output_info;
45544626
4555- output_info = XRRGetOutputInfo (dpy, screen_res, screen_res->outputs [i]);
4627+ output_info = XRRGetOutputInfo (dpy,
4628+ screen_res, screen_res->outputs [i]);
45564629 if (output_info->crtc )
45574630 {
45584631 XRRCrtcInfo *crtc_info;
45594632
4560- crtc_info = XRRGetCrtcInfo (dpy, screen_res, output_info->crtc );
4633+ crtc_info = XRRGetCrtcInfo (dpy,
4634+ screen_res, output_info->crtc );
45614635
45624636 monitors[mi].screen_id = defScreen;
45634637 monitors[mi].depth = [self windowDepthForScreen: mi];
4564- monitors[mi].resolution = [self resolutionForScreen: defScreen];
4565- /* Transform coordinates from Xlib (flipped) to OpenStep (unflippped).
4566- Windows and screens should have the same coordinate system. */
4567- monitors[mi].frame =
4568- NSMakeRect (crtc_info->x ,
4569- xScreenSize.height - crtc_info->height - crtc_info->y ,
4570- crtc_info->width ,
4571- crtc_info->height );
4638+ monitors[mi].resolution
4639+ = [self resolutionForScreen: defScreen];
4640+ if ([workAreas count ] > mi)
4641+ {
4642+ monitors[mi].frame =
4643+ [[workAreas objectAtIndex: mi] rectValue ];
4644+ }
4645+ else
4646+ {
4647+ /* Transform coordinates from Xlib (flipped)
4648+ * to OpenStep (unflipped).
4649+ * Windows and screens should have the same
4650+ * coordinate system.
4651+ */
4652+ monitors[mi].frame =
4653+ NSMakeRect (crtc_info->x ,
4654+ xScreenSize.height - crtc_info->height - crtc_info->y ,
4655+ crtc_info->width ,
4656+ crtc_info->height );
4657+ }
45724658 /* Add monitor ID (index in monitors array).
4573- Put primary monitor ID at index 0 since NSScreen get this as main
4574- screen if application has no key window. */
4659+ * Put primary monitor ID at index 0 since
4660+ * NSScreen gets this as main screen if application
4661+ * has no key window.
4662+ */
45754663 if (screen_res->outputs [i] == primary_output)
45764664 {
4577- [tmpScreens insertObject: [NSNumber numberWithInt: mi] atIndex: 0 ];
4665+ [tmpScreens insertObject: [NSNumber numberWithInt: mi]
4666+ atIndex: 0 ];
45784667 }
45794668 else
45804669 {
@@ -4611,6 +4700,11 @@ - (NSArray *)screenList
46114700 monitors[0 ].depth = [self windowDepthForScreen: 0 ];
46124701 monitors[0 ].resolution = [self resolutionForScreen: defScreen];
46134702 monitors[0 ].frame = NSMakeRect (0 , 0 , xScreenSize.width , xScreenSize.height );
4703+
4704+ if ([workAreas count ] > 0 )
4705+ {
4706+ monitors[0 ].frame = [[workAreas firstObject ] rectValue ];
4707+ }
46144708 return [NSArray arrayWithObject: [NSNumber numberWithInt: defScreen]];
46154709}
46164710
@@ -4861,8 +4955,7 @@ - (unsigned int) desktopNumberForScreen: (int)screen
48614955 unsigned int number = 0 ;
48624956
48634957 num = (unsigned int *)PropGetCheckProperty (dpy, RootWindow (dpy, screen),
4864- generic._NET_CURRENT_DESKTOP_ATOM , XA_CARDINAL,
4865- 32 , 1 , &c);
4958+ generic._NET_CURRENT_DESKTOP_ATOM , XA_CARDINAL, 32 , 1 , &c);
48664959
48674960 if (num)
48684961 {
@@ -4897,8 +4990,7 @@ - (unsigned int) desktopNumberForWindow: (int)win
48974990 return 0 ;
48984991
48994992 num = (unsigned int *)PropGetCheckProperty (dpy, window->ident ,
4900- generic._NET_WM_DESKTOP_ATOM , XA_CARDINAL,
4901- 32 , 1 , &c);
4993+ generic._NET_WM_DESKTOP_ATOM , XA_CARDINAL, 32 , 1 , &c);
49024994
49034995 if (num)
49044996 {
0 commit comments