[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    Re: Disabled windows can't be resized by WM
From:       gerard patel <g.patel () wanadoo ! fr>
Date:       2000-09-25 14:52:55
[Download RAW message or body]

At 09:54 AM 9/22/00 +0800, you wrote:
>I just can't believe! That means, that this code (already existing in x11drv), will
>crash for you if, say, application shows "About" dialog and then will center it
>relatively main window by SetWindowPos. Could you confirm it?

Yes

>Though, this may mean, that wnd->rectWindow has wrong or just zero size for you.

No

>If this is the case, then I couldn't help to trace it, it will be your job, sorry.

Sorry for being late, but it has taken me some time.
It seems it's a Kde 1.1.1 or machine-specific problem.
I can't prove it, but I installed Kde2 (that the reason for the delay :-(),
and if I get to launch Wine in the few time available before 2 crashes <g>,
the problem can't be seen.

Your problem (the vanishing icons) is probably a Kde1.1.1 bug. I'm not
seeing it because I suffer from this other problem, more elusive.

Look at this code from kwm (the Kde 1.1.1 windows manager) :

void Manager::getWMNormalHints(Client *c){
  long msize;
  bool fixedSize = c->fixedSize();
  if (XGetWMNormalHints(qt_xdisplay(), c->window, &c->size, &msize) == 0 || c->size.flags == 0)
    c->size.flags = PSize;      /* not specified - punt */
  if (c->fixedSize() != fixedSize)
    c->reconfigure();
}    

When you are setting (or un-setting) a fixed size for the window, the windows manager reacts, its goal
being to remove/show the maximize/minimize buttons of the window.

void Client::reconfigure(){
   int i;
   for (i=0;i<6;i++){
     if (buttons[i]){
       buttons[i]->hide();
       delete buttons[i];
       buttons[i] = 0;
     }
   }
   generateButtons();
   layoutButtons();
   paintState(false, true);
   doButtonGrab();
}     

All right yet.

But after that, I think there is a problem.
You need to understand what is the meaning of 'trans' boolean in
the following code.
In this case, trans is true; Borland creates all the top-level windows as
either owned popups or even owned overlapped windows, the owner being
a zero-sized (not visible) window. As these windows have an owner, Wine
X driver make them 'transient' X windows (transient means something
like dialog box in the X lingo). Transient windows have no minimize or maximize
buttons (for most X window managers, the only requirement in the ICCM 
norm is that they *can* have 'lighter decoration')

void Client::generateButtons(){
  int i;
 
  buttonMaximize = 0;
  buttonSticky = 0;
  buttonMenu = 0;
 
  for (i=0;i<6;i++){
 
      if (!(buttons[i] = getNewButton( options.buttons[i])))
          continue;
 
      if (getDecoration() != KWM::normalDecoration ) {
          buttons[i]->hide();
          continue;
      }
 
      if (!trans){
          buttons[i]->show();
          continue;
      }
 
      // transient windows, only menu and close on the first resp. last position possible
      if ( (i == 0) && (buttons[i] == buttonMenu) )
          continue;
      if ( (i == 3) && (options.buttons[3] == CLOSE) )
          continue;
      buttons[i]->hide();
  }                  


What I understand from the Kwm code is that once reconfigured, a transient
X window loses the menu and close buttons. I may be wrong but I think Kwm
has not hitten this bug too often because it is probably not common for X program
to reconfigure transient windows. It's only in Wine that transient windows are
alive for the entire duration of the program I guess :-)

The Kwm code works because :
- when the window is created, trans is always true.
- when the transient property is set, the reconfigure() routine
is not called, the buttons are hidden separately :

  case XA_WM_TRANSIENT_FOR:
    // this probably never happens. Care anyway...
    getWindowTrans(c);
    if(c->trans != None){
      int i;
      if (c->buttons[0] && c->buttons[0] != c->buttonMenu)
        c->buttons[0]->hide();
      if (c->buttons[3] && options.buttons[3] != CLOSE)
        c->buttons[3]->hide();
      for (i=1; i<6; i++){
        if ( i != 3 && c->buttons[i])
          c->buttons[i]->hide();
      }
    }
    return;     

I think your patch has hitten squarely a case not forethought by Kwm
programmers.

The kde2 code is rewritten completely BTW.

As of your patch, I can live with it. But I think it's dangerous to want
to fight too hard with windows managers. Or owned popups should not
be transient windows. It's a difficult problem, you'll see that Corel
has a completely different solution in their tree. I am not sure there is
a good solution, in fact.

Gerard

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic