~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201207201942

« back to all changes in this revision

Viewing changes to lib/unity/unityPlatformX11Window.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-03-20 10:19:00 UTC
  • mfrom: (1.1.4 upstream) (2.4.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090320101900-1o604camiubq2de8
Tags: 2009.03.18-154848-2
Correcting patch system depends (Closes: #520493).

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
                               UnityPlatformWindow *upw,
78
78
                               Window toplevelWindow,
79
79
                               Window clientWindow);
80
 
 
 
80
static Window UPWindowLookupClientLeader(UnityPlatform *up,
 
81
                                         UnityPlatformWindow *upw);
81
82
 
82
83
#ifdef VMX86_DEVEL
83
84
/*
449
450
      XSelectInput(up->display, upw->clientWindow, 0);
450
451
      HashTable_Delete(up->allWindows, GUINT_TO_POINTER(upw->clientWindow));
451
452
   }
 
453
#if defined(VM_HAVE_X11_SHAPE_EXT)
 
454
   if (up->shapeEventBase) {
 
455
      XShapeSelectInput(up->display, upw->toplevelWindow, 0);
 
456
 
 
457
      if (upw->clientWindow) {
 
458
         XShapeSelectInput(up->display, upw->clientWindow, 0);
 
459
      }
 
460
   }
 
461
#endif
452
462
 
453
463
   /*
454
464
    * Okay, now we may have two UnityPlatformWindows running around, one each for
487
497
#if defined(VM_HAVE_X11_SHAPE_EXT)
488
498
   if (up->shapeEventBase) {
489
499
      XShapeSelectInput(up->display, toplevelWindow, ShapeNotifyMask);
 
500
 
 
501
      if (upw->clientWindow) {
 
502
         XShapeSelectInput(up->display, upw->clientWindow, ShapeNotifyMask);
 
503
      }
490
504
   }
491
505
#endif
492
506
 
1036
1050
                  return;
1037
1051
               }
1038
1052
            } else if (event->atom == up->atoms._NET_WM_DESKTOP) {
 
1053
               if (upw->wantSetDesktopNumberOnUnmap) {
 
1054
                  /*
 
1055
                   * We're to preserve _NET_WM_DESKTOP across unmapping and remapping a
 
1056
                   * window (most likely a taskbar).  If we see PropertyDelete, assume
 
1057
                   * it's ours and reset the _NET_WM_DESKTOP property.  If, however, we
 
1058
                   * instead see a PropertyNewValue (the only other possibility, hence
 
1059
                   * no "else" below), then we assume some other client wished to change
 
1060
                   * the property, and we forget about restoring _NET_WM_DESKTOP when
 
1061
                   * we remap the window later.
 
1062
                   */
 
1063
                  if (event->state == PropertyDelete) {
 
1064
                     Debug("%s: PropertyDelete: _NET_WM_DESKTOP: %#lx.  Resetting to %d.\n",
 
1065
                           __func__, upw->clientWindow, upw->onUnmapDesktopNumber);
 
1066
                     UPWindow_SetEWMHDesktop(up, upw, upw->onUnmapDesktopNumber);
 
1067
                  }
 
1068
                  upw->wantSetDesktopNumberOnUnmap = FALSE;
 
1069
                  return;
 
1070
               }
1039
1071
               regetDesktop = TRUE;
1040
1072
            } else if (event->atom != up->atoms._NET_WM_WINDOW_TYPE) {
1041
1073
               return;
1064
1096
         break;
1065
1097
 
1066
1098
      case MapNotify:
 
1099
         if (upw->wantSetDesktopNumberOnUnmap) {
 
1100
            Debug("%s: Expected PropertyDelete before MapNotify.\n", __func__);
 
1101
            upw->wantSetDesktopNumberOnUnmap = FALSE;
 
1102
         }
1067
1103
         regetDesktop = TRUE;
1068
1104
         break;
1069
1105
 
1120
1156
      if (regetDesktop) {
1121
1157
         if (!UPWindowGetDesktop(up, upw, &upw->desktopNumber)) {
1122
1158
            upw->desktopNumber = -1;
 
1159
         } else {
 
1160
            if (upw->wantSetDesktopNumberOnUnmap) {
 
1161
               upw->onUnmapDesktopNumber = upw->desktopNumber;
 
1162
            }
1123
1163
         }
1124
1164
      }
1125
1165
      if (upw->desktopNumber < up->desktopInfo.numDesktops
1694
1734
   int numQueryArgs;
1695
1735
   int i;
1696
1736
   int err;
1697
 
   char *ctmp = NULL;
1698
1737
   char **argv;
1699
1738
   char *windowQueryString = NULL;
1700
1739
   char *execQueryString = NULL;
1719
1758
   }
1720
1759
 
1721
1760
   if (argv[0][0] != '/') {
 
1761
      char *ctmp = NULL;
1722
1762
      if ((ctmp = AppUtil_CanonicalizeAppName(argv[0], cwd))) {
1723
1763
         char **newArgv;
1724
1764
         newArgv = alloca(argc * sizeof argv[0]);
1915
1955
   int ret;
1916
1956
   Window checkWindow;
1917
1957
   Bool retval = FALSE;
 
1958
   Bool triedLeader = FALSE;
1918
1959
 
1919
1960
   checkWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
1920
1961
 
 
1962
tryLeader:
1921
1963
   UnityPlatformResetErrorCount(up);
1922
1964
   ret = XGetWindowProperty(up->display, checkWindow, up->atoms._NET_WM_PID, 0,
1923
1965
                            1024, False, AnyPropertyType,
1958
2000
 
1959
2001
   if (!retval && XGetClassHint(up->display, checkWindow, &classHint)) {
1960
2002
      /*
1961
 
       * Last-ditch - try finding the WM_CLASS on $PATH.
 
2003
       * Try finding the WM_CLASS on $PATH.
1962
2004
       */
1963
2005
 
1964
2006
      char *fakeArgv[2] = {NULL, NULL};
1978
2020
      XFree(classHint.res_class);
1979
2021
   }
1980
2022
 
 
2023
   if (!retval && !triedLeader) {
 
2024
      /*
 
2025
       * Last ditch - look for a client leader window and try all of the above
 
2026
       * again.
 
2027
       */
 
2028
      checkWindow = UPWindowLookupClientLeader(up, upw);
 
2029
      if (checkWindow != None) {
 
2030
         triedLeader = TRUE;
 
2031
         goto tryLeader;
 
2032
      }
 
2033
   }
 
2034
 
1981
2035
   Debug("UnityX11GetWindowPath(%#lx) returning %s\n", upw->toplevelWindow,
1982
2036
         retval ? "TRUE" : "FALSE");
1983
2037
 
2515
2569
   XFree(rects); rects = NULL;
2516
2570
   rectCount = 0;
2517
2571
 
 
2572
   /*
 
2573
    * The X Shape Extension operates on unshaped windows by using default bounding
 
2574
    * and clipping regions.  I.e., XShapeGetRectangles will return a single rectangle
 
2575
    * for an unshaped window.  Without the following test, we'd end up informing the
 
2576
    * Unity client that this window can be described by a single rectangle region,
 
2577
    * and it'd expect further region updates when the window's geometry changes.
 
2578
    *
 
2579
    * This wouldn't be a problem, except we don't receive XShapeEvents on these
 
2580
    * windows when they're resized.  To work around this, we make sure that the UWT
 
2581
    * knows that unshaped windows are exactly that.
 
2582
    */
 
2583
   {
 
2584
      int bShaped;
 
2585
      int cShaped;
 
2586
      int dummy;
 
2587
 
 
2588
      XShapeQueryExtents(up->display, upw->toplevelWindow,
 
2589
                         &bShaped, &dummy, &dummy, &dummy, &dummy,
 
2590
                         &cShaped, &dummy, &dummy, &dummy, &dummy);
 
2591
      if (!bShaped && !cShaped) {
 
2592
         UnityWindowTracker_ChangeWindowRegion(up->tracker, upw->toplevelWindow, 0);
 
2593
         return;
 
2594
      }
 
2595
   }
 
2596
 
2518
2597
   UnityPlatformResetErrorCount(up);
2519
2598
 
2520
2599
   /*
3703
3782
                              UnityDesktopId desktopId)  // IN
3704
3783
{
3705
3784
   UnityPlatformWindow *upw;
3706
 
   Atom data[5] = {0, 0, 0, 0, 0};
3707
3785
   uint32 guestDesktopId;
3708
3786
 
3709
3787
   ASSERT(up);
3727
3805
   ASSERT(desktopId < up->desktopInfo.numDesktops);
3728
3806
   guestDesktopId = up->desktopInfo.unityDesktopToGuest[desktopId];
3729
3807
 
3730
 
   if (!upw->isViewable) {
3731
 
     Atom currentDesktop = guestDesktopId; // Cast for 64-bit correctness.
 
3808
   UPWindow_SetEWMHDesktop(up, upw, guestDesktopId);
 
3809
 
 
3810
   return TRUE;
 
3811
}
 
3812
 
 
3813
 
 
3814
/*
 
3815
 *------------------------------------------------------------------------------
 
3816
 *
 
3817
 * UPWindow_SetEWMHDesktop --
 
3818
 *
 
3819
 *     Move the window to the specified desktop.  ewmhDesktopId corresponds
 
3820
 *     to a desktop index to be used with _NET_WM_DESKTOP.
 
3821
 *
 
3822
 * Results:
 
3823
 *     This will directly change _NET_WM_DESKTOP of an unmapped window,
 
3824
 *     and will instead request the window manager to update that property
 
3825
 *     for a mapped window.
 
3826
 *
 
3827
 * Side effects:
 
3828
 *     None.
 
3829
 *
 
3830
 *------------------------------------------------------------------------------
 
3831
 */
 
3832
 
 
3833
 
 
3834
void
 
3835
UPWindow_SetEWMHDesktop(UnityPlatform *up,               // IN
 
3836
                        UnityPlatformWindow *upw,        // IN
 
3837
                        uint32 ewmhDesktopId)            // IN
 
3838
{
 
3839
   Atom data[5] = {0, 0, 0, 0, 0};
 
3840
 
 
3841
   ASSERT(up);
 
3842
   ASSERT(upw);
 
3843
 
 
3844
   if (!upw->isViewable || upw->wantSetDesktopNumberOnUnmap) {
 
3845
     Atom currentDesktop = ewmhDesktopId; // Cast for 64-bit correctness.
3732
3846
 
3733
3847
     /*
3734
3848
      * Sending the _NET_WM_DESKTOP client message only works if the
3736
3850
      * eliminate race conditions, but if the window is not mapped, we
3737
3851
      * also need to set the property on the window so that it shows
3738
3852
      * up on the correct desktop when it is re-mapped.
 
3853
      *
 
3854
      * wantSetDesktopNumberOnUnmap implies that we unmapped the window
 
3855
      * in question.  We evaluate this here, in addition to isViewable,
 
3856
      * because it's totally possible that the window server processed
 
3857
      * our unmap request, but we just haven't received the notification
 
3858
      * yet.  (In other words, if that's the case, isViewable may still
 
3859
      * be TRUE.)
3739
3860
      */
3740
3861
 
3741
3862
     XChangeProperty(up->display, (Window)upw->clientWindow, up->atoms._NET_WM_DESKTOP,
3742
3863
                     XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&currentDesktop, 1);
3743
3864
   }
3744
3865
 
3745
 
   data[0] = guestDesktopId;
 
3866
   data[0] = ewmhDesktopId;
3746
3867
   data[1] = 2; // Indicates that this was requested by the pager/taskbar/etc.
3747
3868
   UnityPlatformSendClientMessage(up,
3748
3869
                                  upw->rootWindow,
3749
3870
                                  upw->clientWindow,
3750
3871
                                  up->atoms._NET_WM_DESKTOP,
3751
3872
                                  32, 5, data);
3752
 
 
3753
 
   return TRUE;
 
3873
}
 
3874
 
 
3875
 
 
3876
/*
 
3877
 *-----------------------------------------------------------------------------
 
3878
 *
 
3879
 * UPWindowLookupClientLeader --
 
3880
 *
 
3881
 *      Given a UnityPlatformWindow, look up the associated "client leader"
 
3882
 *      window, identified by the WM_CLIENT_LEADER property, if it exists.
 
3883
 *
 
3884
 * Results:
 
3885
 *      A valid window ID if found, otherwise None.
 
3886
 *
 
3887
 * Side effects:
 
3888
 *      None.
 
3889
 *
 
3890
 *-----------------------------------------------------------------------------
 
3891
 */
 
3892
 
 
3893
static Window
 
3894
UPWindowLookupClientLeader(UnityPlatform *up,           // IN
 
3895
                           UnityPlatformWindow *upw)    // IN
 
3896
{
 
3897
   Atom propertyType;
 
3898
   int propertyFormat;
 
3899
   unsigned long itemsReturned;
 
3900
   unsigned long bytesRemaining;
 
3901
   unsigned char *valueReturned = NULL;
 
3902
 
 
3903
   Window checkWindow;
 
3904
   Window leaderWindow = None;
 
3905
 
 
3906
   ASSERT(up);
 
3907
   ASSERT(upw);
 
3908
 
 
3909
   checkWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
 
3910
 
 
3911
   UnityPlatformResetErrorCount(up);
 
3912
   XGetWindowProperty(up->display, checkWindow, up->atoms.WM_CLIENT_LEADER, 0,
 
3913
                      4, False, XA_WINDOW, &propertyType, &propertyFormat,
 
3914
                      &itemsReturned, &bytesRemaining, &valueReturned);
 
3915
 
 
3916
   if (UnityPlatformGetErrorCount(up) == 0 && propertyFormat == 32 &&
 
3917
       itemsReturned == 1) {
 
3918
      leaderWindow = *(XID *)valueReturned;
 
3919
   }
 
3920
 
 
3921
   XFree(valueReturned);
 
3922
 
 
3923
   return leaderWindow;
3754
3924
}