예제 #1
0
파일: place.c 프로젝트: KarlGodt/jwm
/** Centered placement. */
void CenterClient(const BoundingBox *box, ClientNode *np)
{
   np->x = box->x + (box->width / 2) - (np->width / 2);
   np->y = box->y + (box->height / 2) - (np->height / 2);
   ConstrainSize(np);
   ConstrainPosition(np);
}
예제 #2
0
void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
{
    wxCHECK_RET( m_widget, wxT("invalid frame") );

    // deal with the position first
    int old_x = m_x;
    int old_y = m_y;

    if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
    {
        // -1 means "use existing" unless the flag above is specified
        if ( x != -1 )
            m_x = x;
        if ( y != -1 )
            m_y = y;
    }
    else // wxSIZE_ALLOW_MINUS_ONE
    {
        m_x = x;
        m_y = y;
    }

    const wxSize oldSize(m_width, m_height);
    if (width >= 0)
        m_width = width;
    if (height >= 0)
        m_height = height;
    ConstrainSize();
    if (m_width < 1) m_width = 1;
    if (m_height < 1) m_height = 1;

    if ( m_x != old_x || m_y != old_y )
    {
        gtk_window_move( GTK_WINDOW(m_widget), m_x, m_y );
        wxMoveEvent event(wxPoint(m_x, m_y), GetId());
        event.SetEventObject(this);
        HandleWindowEvent(event);
    }

    if (m_width != oldSize.x || m_height != oldSize.y)
    {
        m_deferShowAllowed = true;
        m_useCachedClientSize = false;

        int w, h;
        GTKDoGetSize(&w, &h);
        gtk_window_resize(GTK_WINDOW(m_widget), w, h);
        if (!gtk_window_get_resizable(GTK_WINDOW(m_widget)))
            gtk_widget_set_size_request(GTK_WIDGET(m_widget), w, h);

        DoGetClientSize(&m_clientWidth, &m_clientHeight);
        wxSizeEvent event(GetSize(), GetId());
        event.SetEventObject(this);
        HandleWindowEvent(event);
    }
}
예제 #3
0
파일: place.c 프로젝트: KarlGodt/jwm
/** Cascade placement. */
void CascadeClient(const BoundingBox *box, ClientNode *np)
{

   const ScreenType *sp;
   int north, south, east, west;
   int cascadeIndex;
   char overflow;

   GetBorderSize(&np->state, &north, &south, &east, &west);
   sp = GetMouseScreen();
   cascadeIndex = sp->index * settings.desktopCount + currentDesktop;

   /* Set the cascaded location. */
   np->x = box->x + west + cascadeOffsets[cascadeIndex];
   np->y = box->y + north + cascadeOffsets[cascadeIndex];
   cascadeOffsets[cascadeIndex] += settings.borderWidth
                                 + settings.titleHeight;

   /* Check for cascade overflow. */
   overflow = 0;
   if(np->x + np->width - box->x > box->width) {
      overflow = 1;
   } else if(np->y + np->height - box->y > box->height) {
      overflow = 1;
   }

   if(overflow) {
      cascadeOffsets[cascadeIndex] = settings.borderWidth
                                   + settings.titleHeight;
      np->x = box->x + west + cascadeOffsets[cascadeIndex];
      np->y = box->y + north + cascadeOffsets[cascadeIndex];

      /* Check for client overflow and update cascade position. */
      if(np->x + np->width - box->x > box->width) {
         np->x = box->x + west;
      } else if(np->y + np->height - box->y > box->height) {
         np->y = box->y + north;
      } else {
         cascadeOffsets[cascadeIndex] += settings.borderWidth
                                       + settings.titleHeight;
      }
   }

   ConstrainSize(np);
   ConstrainPosition(np);

}
예제 #4
0
파일: place.c 프로젝트: KarlGodt/jwm
/** Place a client on the screen. */
void PlaceClient(ClientNode *np, char alreadyMapped)
{

   BoundingBox box;
   const ScreenType *sp;

   Assert(np);

   if(alreadyMapped || (!(np->state.status & STAT_PIGNORE)
                        && (np->sizeFlags & (PPosition | USPosition)))) {

      GravitateClient(np, 0);
      if(!alreadyMapped) {
         ConstrainSize(np);
         ConstrainPosition(np);
      }

   } else {

      sp = GetMouseScreen();
      GetScreenBounds(sp, &box);
      SubtractTrayBounds(GetTrays(), &box, np->state.layer);
      SubtractStrutBounds(&box, np);

      /* If tiled is specified, first attempt to use tiled placement. */
      if(np->state.status & STAT_TILED) {
         if(TileClient(&box, np)) {
            return;
         }
      }

      /* Either tiled placement failed or was not specified. */
      if(np->state.status & STAT_CENTERED) {
         CenterClient(&box, np);
      } else {
         CascadeClient(&box, np);
      }

   }

}
예제 #5
0
void wxPopupWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
{
    wxASSERT_MSG( (m_widget != NULL), wxT("invalid dialog") );
    wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid dialog") );

    int old_x = m_x;
    int old_y = m_y;

    int old_width = m_width;
    int old_height = m_height;

    if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
        m_x = x;
    if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
        m_y = y;
    if (width != -1)
        m_width = width;
    if (height != -1)
        m_height = height;

    ConstrainSize();

    if (m_x != old_x || m_y != old_y)
    {
        gtk_window_move(GTK_WINDOW(m_widget), m_x, m_y);
        wxMoveEvent event(wxPoint(m_x, m_y), GetId());
        event.SetEventObject(this);
        HandleWindowEvent(event);
    }

    if ((m_width != old_width) || (m_height != old_height))
    {
        // gtk_window_resize does not work for GTK_WINDOW_POPUP
        gtk_widget_set_size_request( m_widget, m_width, m_height );
        wxSizeEvent event(GetSize(), GetId());
        event.SetEventObject(this);
        HandleWindowEvent(event);
    }
}
예제 #6
0
/*
 * ValidateSizing - Ensures size request respects hints
 */
static int
ValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
{
    WinXSizeHints sizeHints;
    RECT *rect;
    int iWidth, iHeight, iTopBorder;
    POINT pt;

    /* Invalid input checking */
    if (pWin == NULL || lParam == 0) {
        ErrorF("Invalid input checking\n");
        return FALSE;
    }

    /* No size hints, no checking */
    if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints)) {
        ErrorF("No size hints, no checking\n");
        return FALSE;
    }

    /* Avoid divide-by-zero */
    if (sizeHints.flags & PResizeInc) {
        if (sizeHints.width_inc == 0)
            sizeHints.width_inc = 1;
        if (sizeHints.height_inc == 0)
            sizeHints.height_inc = 1;
    }

    rect = (RECT *) lParam;

    iWidth = rect->right - rect->left;
    iHeight = rect->bottom - rect->top;

    /* Get title bar height, there must be an easier way?! */
    pt.x = pt.y = 0;
    ClientToScreen(hwnd, &pt);
    iTopBorder = pt.y - rect->top;

    /* Now remove size of any borders */
    iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
    iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;

    /* Constrain the size to legal values */
    ConstrainSize(sizeHints, &iWidth, &iHeight);

    /* Add back the borders */
    iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
    iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;

    /* Adjust size according to where we're dragging from */
    switch (wParam) {
    case WMSZ_TOP:
    case WMSZ_TOPRIGHT:
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_RIGHT:
        rect->right = rect->left + iWidth;
        break;
    default:
        rect->left = rect->right - iWidth;
        break;
    }
    switch (wParam) {
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_BOTTOMLEFT:
    case WMSZ_RIGHT:
    case WMSZ_LEFT:
        rect->bottom = rect->top + iHeight;
        break;
    default:
        rect->top = rect->bottom - iHeight;
        break;
    }
    return TRUE;
}
예제 #7
0
/**
*** MakeButton()
*** To position subwindows in a button: icons and swallowed windows.
**/
void MakeButton(button_info *b)
{
  /* This is resposible for drawing the contents of a button, placing the
     icon and/or swallowed item in the correct position inside potential
     padding or frame.
  */
  int ih,iw,ix,iy;
  XFontStruct *font;

  if(!b)
    {
      fprintf(stderr,"%s: BUG: DrawButton called with NULL pointer\n",MyName);
      exit(2);
    }
  if(b->flags&b_Container)
    {
      fprintf(stderr,"%s: BUG: DrawButton called with container\n",MyName);
      exit(2);
    }

  if(!(b->flags&b_Icon) && (buttonSwallowCount(b)<3))
    return;

  font = buttonFont(b);

  GetInternalSize(b,&ix,&iy,&iw,&ih);

  /* At this point iw,ih,ix and iy should be correct. Now all we have to do is
     place title and iconwin in their proper positions */

  /* For now, use the old routine in icons.h for buttons with icons */
  if(b->flags&b_Icon)
    ConfigureIconWindow(b);

  /* For now, hardcoded window centered, title bottom centered, below window */
  else if(buttonSwallowCount(b)==3)
    {
      long supplied;
      if(!b->IconWin)
	{
	  fprintf(stderr,"%s: BUG: Swallowed window has no IconWin\n",MyName);
	  exit(2);
	}

      if(b->flags&b_Title && font && !(buttonJustify(b)&b_Horizontal))
	ih -= font->ascent+font->descent;
	
      b->icon_w=iw;
      b->icon_h=ih;

      if(iw>0 && ih>0)
	{
	  if(!(buttonSwallow(b)&b_NoHints))
	    {
	      if(!XGetWMNormalHints(Dpy,b->IconWin,b->hints,&supplied))
		b->hints->flags=0;
	      ConstrainSize(b->hints,&b->icon_w,&b->icon_h);
	    }
	  XMoveResizeWindow(Dpy,b->IconWin,ix+(iw-b->icon_w)/2,
			    iy+(ih-b->icon_h)/2,b->icon_w,b->icon_h);
	}
      else
	XMoveWindow(Dpy,b->IconWin,2000,2000);	
    }
}
예제 #8
0
파일: event.c 프로젝트: pecarter-work/jwm
/** Handle a property notify event. */
char HandlePropertyNotify(const XPropertyEvent *event)
{
   ClientNode *np = FindClientByWindow(event->window);
   if(np) {
      char changed = 0;
      switch(event->atom) {
      case XA_WM_NAME:
         ReadWMName(np);
         changed = 1;
         break;
      case XA_WM_NORMAL_HINTS:
         ReadWMNormalHints(np);
         if(ConstrainSize(np)) {
            ResetBorder(np);
         }
         changed = 1;
         break;
      case XA_WM_HINTS:
         if(np->state.status & STAT_URGENT) {
            UnregisterCallback(SignalUrgent, np);
         }
         ReadWMHints(np->window, &np->state, 1);
         if(np->state.status & STAT_URGENT) {
            RegisterCallback(URGENCY_DELAY, SignalUrgent, np);
         }
         WriteState(np);
         break;
      case XA_WM_TRANSIENT_FOR:
         JXGetTransientForHint(display, np->window, &np->owner);
         break;
      case XA_WM_ICON_NAME:
      case XA_WM_CLIENT_MACHINE:
         break;
      default:
         if(event->atom == atoms[ATOM_WM_COLORMAP_WINDOWS]) {
            ReadWMColormaps(np);
            UpdateClientColormap(np);
         } else if(event->atom == atoms[ATOM_WM_PROTOCOLS]) {
            ReadWMProtocols(np->window, &np->state);
         } else if(event->atom == atoms[ATOM_NET_WM_ICON]) {
            LoadIcon(np);
            changed = 1;
         } else if(event->atom == atoms[ATOM_NET_WM_NAME]) {
            ReadWMName(np);
            changed = 1;
         } else if(event->atom == atoms[ATOM_NET_WM_STRUT_PARTIAL]) {
            ReadClientStrut(np);
         } else if(event->atom == atoms[ATOM_NET_WM_STRUT]) {
            ReadClientStrut(np);
         } else if(event->atom == atoms[ATOM_MOTIF_WM_HINTS]) {
            UpdateState(np);
            WriteState(np);
            ResetBorder(np);
            changed = 1;
         } else if(event->atom == atoms[ATOM_NET_WM_WINDOW_OPACITY]) {
            ReadWMOpacity(np->window, &np->state.opacity);
            if(np->parent != None) {
               SetOpacity(np, np->state.opacity, 1);
            }
         }
         break;
      }

      if(changed) {
         DrawBorder(np);
         RequireTaskUpdate();
         RequirePagerUpdate();
      }
      if(np->state.status & STAT_WMDIALOG) {
         return 0;
      } else {
         return 1;
      }
   }

   return 1;
}
예제 #9
0
파일: event.c 프로젝트: pecarter-work/jwm
/** Process a configure request. */
void HandleConfigureRequest(const XConfigureRequestEvent *event)
{
   XWindowChanges wc;
   ClientNode *np;

   if(HandleDockConfigureRequest(event)) {
      return;
   }

   np = FindClientByWindow(event->window);
   if(np) {

      int deltax, deltay;
      char changed = 0;
      char resized = 0;

      GetGravityDelta(np, np->gravity, &deltax, &deltay);
      if((event->value_mask & CWWidth) && (event->width != np->width)) {
         switch(np->gravity) {
         case EastGravity:
         case NorthEastGravity:
         case SouthEastGravity:
            /* Right side should not move. */
            np->x -= event->width - np->width;
            break;
         case WestGravity:
         case NorthWestGravity:
         case SouthWestGravity:
            /* Left side should not move. */
            break;
         case CenterGravity:
            /* Center of the window should not move. */
            np->x -= (event->width - np->width) / 2;
            break;
         default:
            break;
         }
         np->width = event->width;
         changed = 1;
         resized = 1;
      }
      if((event->value_mask & CWHeight) && (event->height != np->height)) {
         switch(np->gravity) {
         case NorthGravity:
         case NorthEastGravity:
         case NorthWestGravity:
            /* Top should not move. */
            break;
         case SouthGravity:
         case SouthEastGravity:
         case SouthWestGravity:
            /* Bottom should not move. */
            np->y -= event->height - np->height;
            break;
         case CenterGravity:
            /* Center of the window should not move. */
            np->y -= (event->height - np->height) / 2;
            break;
         default:
            break;
         }
         np->height = event->height;
         changed = 1;
         resized = 1;
      }
      if((event->value_mask & CWX) && (event->x - deltax != np->x)) {
         np->x = event->x - deltax;
         changed = 1;
      }
      if((event->value_mask & CWY) && (event->y - deltay != np->y)) {
         np->y = event->y - deltay;
         changed = 1;
      }

      /* Update stacking. */
      if((event->value_mask & CWStackMode)) {
         Window above = None;
         if(event->value_mask & CWSibling) {
            above = event->above;
         }
         RestackClient(np, above, event->detail);
      }

      /* Return early if there's nothing to do. */
      if(!changed) {
         return;
      }

      if(np->controller) {
         (np->controller)(0);
      }
      if(np->state.maxFlags) {
         MaximizeClient(np, MAX_NONE);
      }

      if(np->state.border & BORDER_CONSTRAIN) {
         resized = 1;
      }
      if(resized) {
         ConstrainSize(np);
         ConstrainPosition(np);
         ResetBorder(np);
      } else {
         int north, south, east, west;
         GetBorderSize(&np->state, &north, &south, &east, &west);
         if(np->parent != None) {
            JXMoveWindow(display, np->parent, np->x - west, np->y - north);
         } else {
            JXMoveWindow(display, np->window, np->x, np->y);
         }
      }

      SendConfigureEvent(np);
      RequirePagerUpdate();

   } else {

      /* We don't know about this window, just let the configure through. */

      wc.stack_mode = event->detail;
      wc.sibling = event->above;
      wc.border_width = event->border_width;
      wc.x = event->x;
      wc.y = event->y;
      wc.width = event->width;
      wc.height = event->height;
      JXConfigureWindow(display, event->window, event->value_mask, &wc);

   }
}
예제 #10
0
파일: event.c 프로젝트: pecarter-work/jwm
/** Handle a _NET_MOVERESIZE_WINDOW request. */
void HandleNetMoveResize(const XClientMessageEvent *event, ClientNode *np)
{

   long flags;
   int gravity;
   int deltax, deltay;

   Assert(event);
   Assert(np);

   flags = event->data.l[0] >> 8;
   gravity = event->data.l[0] & 0xFF;
   if(gravity == 0) {
      gravity = np->gravity;
   }
   GetGravityDelta(np, gravity, &deltax, &deltay);

   if(flags & (1 << 2)) {
      const long width = event->data.l[3];
      switch(gravity) {
      case EastGravity:
      case NorthEastGravity:
      case SouthEastGravity:
         /* Right side should not move. */
         np->x -= width - np->width;
         break;
      case WestGravity:
      case NorthWestGravity:
      case SouthWestGravity:
         /* Left side should not move. */
         break;
      case CenterGravity:
         /* Center of the window should not move. */
         np->x -= (width - np->width) / 2;
         break;
      default:
         break;
      }
      np->width = width;
   }
   if(flags & (1 << 3)) {
      const long height = event->data.l[4];
      switch(gravity) {
      case NorthGravity:
      case NorthEastGravity:
      case NorthWestGravity:
         /* Top should not move. */
         break;
      case SouthGravity:
      case SouthEastGravity:
      case SouthWestGravity:
         /* Bottom should not move. */
         np->y -= height - np->height;
         break;
      case CenterGravity:
         /* Center of the window should not move. */
         np->y -= (height - np->height) / 2;
         break;
      default:
         break;
      }
      np->height = height;
   }
   if(flags & (1 << 0)) {
      np->x = event->data.l[1] - deltax;
   }
   if(flags & (1 << 1)) {
      np->y = event->data.l[2] - deltay;
   }

   /* Don't let maximized clients be moved or resized. */
   if(JUNLIKELY(np->state.status & STAT_FULLSCREEN)) {
      SetClientFullScreen(np, 0);
   }
   if(JUNLIKELY(np->state.maxFlags)) {
      MaximizeClient(np, MAX_NONE);
   }

   ConstrainSize(np);
   ResetBorder(np);
   SendConfigureEvent(np);
   RequirePagerUpdate();

}
예제 #11
0
파일: client.c 프로젝트: pecarter-work/jwm
/** Set a client's full screen state. */
void SetClientFullScreen(ClientNode *np, char fullScreen)
{

   XEvent event;
   int north, south, east, west;
   BoundingBox box;
   const ScreenType *sp;

   Assert(np);

   /* Make sure there's something to do. */
   if(!fullScreen == !(np->state.status & STAT_FULLSCREEN)) {
      return;
   }
   if(!(np->state.border & BORDER_FULLSCREEN)) {
      return;
   }

   if(np->state.status & STAT_SHADED) {
      UnshadeClient(np);
   }

   if(fullScreen) {

      np->state.status |= STAT_FULLSCREEN;

      if(!(np->state.maxFlags)) {
         np->oldx = np->x;
         np->oldy = np->y;
         np->oldWidth = np->width;
         np->oldHeight = np->height;
      }

      sp = GetCurrentScreen(np->x, np->y);
      GetScreenBounds(sp, &box);

      GetBorderSize(&np->state, &north, &south, &east, &west);
      box.x += west;
      box.y += north;
      box.width -= east + west;
      box.height -= north + south;

      np->x = box.x;
      np->y = box.y;
      np->width = box.width;
      np->height = box.height;
      ResetBorder(np);

   } else {

      np->state.status &= ~STAT_FULLSCREEN;

      np->x = np->oldx;
      np->y = np->oldy;
      np->width = np->oldWidth;   
      np->height = np->oldHeight;
      ConstrainSize(np);
      ConstrainPosition(np);

      if(np->state.maxFlags != MAX_NONE) {
         PlaceMaximizedClient(np, np->state.maxFlags);
      }

      ResetBorder(np);

      event.type = MapRequest;
      event.xmaprequest.send_event = True;
      event.xmaprequest.display = display;
      event.xmaprequest.parent = np->parent;
      event.xmaprequest.window = np->window;
      JXSendEvent(display, rootWindow, False,
                  SubstructureRedirectMask, &event);

   }

   WriteState(np);
   SendConfigureEvent(np);
   RequireRestack();

}
예제 #12
0
파일: place.c 프로젝트: KarlGodt/jwm
/** Attempt to place the client at the specified coordinates. */
char TryTileClient(const BoundingBox *box, ClientNode *np, int x, int y)
{
   const ClientNode *tp;
   int layer;
   int north, south, east, west;
   int x1, x2, y1, y2;
   int ox1, ox2, oy1, oy2;

   /* Set the client position. */
   GetBorderSize(&np->state, &north, &south, &east, &west);
   np->x = x + west;
   np->y = y + north;
   ConstrainSize(np);
   ConstrainPosition(np);

   /* Get the client boundaries. */
   x1 = np->x - west;
   x2 = np->x + np->width + east;
   y1 = np->y - north;
   y2 = np->y + np->height + south;

   /* Loop over each client. */
   for(layer = np->state.layer; layer < LAYER_COUNT; layer++) {
      for(tp = nodes[layer]; tp; tp = tp->next) {

         /* Skip clients that aren't visible. */
         if(tp->state.desktop != currentDesktop) {
            if(!(tp->state.status & STAT_STICKY)) {
               continue;
            }
         }
         if(!(tp->state.status & STAT_MAPPED)) {
            continue;
         }
         if(tp == np) {
            continue;
         }

         /* Get the boundaries of the other client. */
         GetBorderSize(&tp->state, &north, &south, &east, &west);
         ox1 = tp->x - west;
         ox2 = tp->x + tp->width + east;
         oy1 = tp->y - north;
         oy2 = tp->y + tp->height + south;

         /* Check for an overlap. */
         if(x2 <= ox1 || x1 >= ox2) {
            continue;
         }
         if(y2 <= oy1 || y1 >= oy2) {
            continue;
         }
         return 0;

      }
   }

   /* No client overlaps this position. */
   return 1;

}
예제 #13
0
/*
 * ValidateSizing - Ensures size request respects hints
 */
static int
ValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
{
    WinXSizeHints sizeHints;
    RECT *rect;
    int iWidth, iHeight;
    RECT rcClient, rcWindow;
    int iBorderWidthX, iBorderWidthY;

    /* Invalid input checking */
    if (pWin == NULL || lParam == 0)
        return FALSE;

    /* No size hints, no checking */
    if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints))
        return FALSE;

    /* Avoid divide-by-zero */
    if (sizeHints.flags & PResizeInc) {
        if (sizeHints.width_inc == 0)
            sizeHints.width_inc = 1;
        if (sizeHints.height_inc == 0)
            sizeHints.height_inc = 1;
    }

    rect = (RECT *) lParam;

    iWidth = rect->right - rect->left;
    iHeight = rect->bottom - rect->top;

    /* Now remove size of any borders and title bar */
    GetClientRect(hwnd, &rcClient);
    GetWindowRect(hwnd, &rcWindow);
    iBorderWidthX =
        (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left);
    iBorderWidthY =
        (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
    iWidth -= iBorderWidthX;
    iHeight -= iBorderWidthY;

    /* Constrain the size to legal values */
    ConstrainSize(sizeHints, &iWidth, &iHeight);

    /* Add back the size of borders and title bar */
    iWidth += iBorderWidthX;
    iHeight += iBorderWidthY;

    /* Adjust size according to where we're dragging from */
    switch (wParam) {
    case WMSZ_TOP:
    case WMSZ_TOPRIGHT:
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_RIGHT:
        rect->right = rect->left + iWidth;
        break;
    default:
        rect->left = rect->right - iWidth;
        break;
    }
    switch (wParam) {
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_BOTTOMLEFT:
    case WMSZ_RIGHT:
    case WMSZ_LEFT:
        rect->bottom = rect->top + iHeight;
        break;
    default:
        rect->top = rect->bottom - iHeight;
        break;
    }
    return TRUE;
}
예제 #14
0
파일: event.c 프로젝트: GustavoMOG/JWM
/** Process a configure request. */
void HandleConfigureRequest(const XConfigureRequestEvent *event) {

   XWindowChanges wc;
   ClientNode *np;
   int north, south, east, west;
   int changed;
   int handled;

   handled = HandleDockConfigureRequest(event);
   if(handled) {
      return;
   }

   np = FindClientByWindow(event->window);
   if(np && np->window == event->window) {

      /* We own this window, make sure it's not trying to do something bad. */
      changed = 0;
      if((event->value_mask & CWWidth) && (event->width != np->width)) {
         if(!(np->state.status & STAT_HMAX)) {
            np->width = event->width;
            changed = 1;
         }
      }
      if((event->value_mask & CWHeight) && (event->height != np->height)) {
         if(!(np->state.status & STAT_VMAX)) {
            np->height = event->height;
            changed = 1;
         }
      }
      if((event->value_mask & CWX) && (event->x != np->x)) {
         if(!(np->state.status & STAT_HMAX)) {
            np->x = event->x;
            changed = 1;
         }
      }
      if((event->value_mask & CWY) && (event->y != np->y)) {
         if(!(np->state.status & STAT_VMAX)) {
            np->y = event->y;
            changed = 1;
         }
      }

      if(!changed) {
         return;
      }

      if(np->controller) {
         (np->controller)(0);
      }

      GetBorderSize(np, &north, &south, &east, &west);

      ResetRoundedRectWindow(np->parent);

      wc.stack_mode = Above;
      wc.sibling = np->parent;
      wc.border_width = 0;

      ConstrainSize(np);

      wc.x = np->x;
      wc.y = np->y;
      wc.width = np->width + east + west;
      wc.height = np->height + north + south;
      JXConfigureWindow(display, np->parent, event->value_mask, &wc);

      wc.x = west;
      wc.y = north;
      wc.width = np->width;
      wc.height = np->height;
      JXConfigureWindow(display, np->window, event->value_mask, &wc);

   } else {

      /* We don't know about this window, just let the configure through. */

      wc.stack_mode = event->detail;
      wc.sibling = event->above;
      wc.border_width = event->border_width;
      wc.x = event->x;
      wc.y = event->y;
      wc.width = event->width > rootWidth ? rootWidth : event->width;
      wc.height = event->height > rootHeight ? rootHeight : event->height;
      JXConfigureWindow(display, event->window, event->value_mask, &wc);

   }

}
예제 #15
0
void HandlePropertyNotify()
{
  XTextProperty text_prop;
  Boolean       OnThisPage    =  False;

  DBUG("HandlePropertyNotify","Routine Entered");

  if ((!Tmp_win)||
      (XGetGeometry(dpy, Tmp_win->w, &JunkRoot, &JunkX, &JunkY,
		    &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0))
    return;

  /*
      Make sure at least part of window is on this page
      before giving it focus...
  */
  if ( (Tmp_win->Desk == Scr.CurrentDesk) &&
       ( ((Tmp_win->frame_x + Tmp_win->frame_width) >= 0 &&
          Tmp_win->frame_x < Scr.MyDisplayWidth) &&
         ((Tmp_win->frame_y + Tmp_win->frame_height) >= 0 &&
          Tmp_win->frame_y < Scr.MyDisplayHeight)
       )
     )
    {
      OnThisPage  =  True;
    }

  switch (Event.xproperty.atom)
    {
    case XA_WM_TRANSIENT_FOR:
      {
        if(XGetTransientForHint(dpy, Tmp_win->w, &Tmp_win->transientfor))
        {
           Tmp_win->flags |= TRANSIENT;
           RaiseWindow(Tmp_win);
        }
        else
        {
           Tmp_win->flags &= ~TRANSIENT;
        }
      }
      break;

    case XA_WM_NAME:
      if (!XGetWMName(dpy, Tmp_win->w, &text_prop))
	return;

      free_window_names (Tmp_win, True, False);

      Tmp_win->name = (char *)text_prop.value;
      if (Tmp_win->name && strlen(Tmp_win->name) > 200)
	/* limit to prevent hanging X server */
	Tmp_win->name[200] = 0;

      if (Tmp_win->name == NULL)
        Tmp_win->name = NoName;
      BroadcastName(M_WINDOW_NAME,Tmp_win->w,Tmp_win->frame,
		    (unsigned long)Tmp_win,Tmp_win->name);

      /* fix the name in the title bar */
      if(!(Tmp_win->flags & ICONIFIED))
	SetTitleBar(Tmp_win,(Scr.Hilite==Tmp_win),True);

      /*
       * if the icon name is NoName, set the name of the icon to be
       * the same as the window
       */
      if (Tmp_win->icon_name == NoName)
	{
	  Tmp_win->icon_name = Tmp_win->name;
	  BroadcastName(M_ICON_NAME,Tmp_win->w,Tmp_win->frame,
			(unsigned long)Tmp_win,Tmp_win->icon_name);
	  RedoIconName(Tmp_win);
	}
      break;

    case XA_WM_ICON_NAME:
      if (!XGetWMIconName (dpy, Tmp_win->w, &text_prop))
	return;
      free_window_names (Tmp_win, False, True);
      Tmp_win->icon_name = (char *) text_prop.value;
      if (Tmp_win->icon_name && strlen(Tmp_win->icon_name) > 200)
	/* limit to prevent hanging X server */
	Tmp_win->icon_name[200] = 0;
      if (Tmp_win->icon_name == NULL)
        Tmp_win->icon_name = NoName;
      BroadcastName(M_ICON_NAME,Tmp_win->w,Tmp_win->frame,
		    (unsigned long)Tmp_win,Tmp_win->icon_name);
      RedoIconName(Tmp_win);
      break;

    case XA_WM_HINTS:
      if (Tmp_win->wmhints)
	XFree ((char *) Tmp_win->wmhints);
      Tmp_win->wmhints = XGetWMHints(dpy, Event.xany.window);

      if(Tmp_win->wmhints == NULL)
	return;

      if((Tmp_win->wmhints->flags & IconPixmapHint)||
	 (Tmp_win->wmhints->flags & IconWindowHint))
	if(Tmp_win->icon_bitmap_file == Scr.DefaultIcon)
	  Tmp_win->icon_bitmap_file = (char *)0;

      if((Tmp_win->wmhints->flags & IconPixmapHint)||
         (Tmp_win->wmhints->flags & IconWindowHint))
	{
	  if (!(Tmp_win->flags & SUPPRESSICON))
	    {
              if (Tmp_win->icon_w)
                XDestroyWindow(dpy,Tmp_win->icon_w);
	      XDeleteContext(dpy, Tmp_win->icon_w, FvwmContext);
	      if(Tmp_win->flags & ICON_OURS)
		{
		  if(Tmp_win->icon_pixmap_w != None)
		    {
		      XDestroyWindow(dpy,Tmp_win->icon_pixmap_w);
		      XDeleteContext(dpy, Tmp_win->icon_pixmap_w, FvwmContext);
		    }
		}
	      else
		XUnmapWindow(dpy,Tmp_win->icon_pixmap_w);
	    }
          Tmp_win->icon_w = None;
          Tmp_win->icon_pixmap_w = None;
	  Tmp_win->iconPixmap = (Window)NULL;
	  if(Tmp_win->flags & ICONIFIED)
	    {
	      Tmp_win->flags &= ~ICONIFIED;
	      Tmp_win->flags &= ~ICON_UNMAPPED;
	      CreateIconWindow(Tmp_win,
			       Tmp_win->icon_x_loc,Tmp_win->icon_y_loc);
	      BroadcastPacket(M_ICONIFY, 7,
                              Tmp_win->w, Tmp_win->frame,
                              (unsigned long)Tmp_win,
                              Tmp_win->icon_x_loc, Tmp_win->icon_y_loc,
                              Tmp_win->icon_w_width, Tmp_win->icon_w_height);
	      BroadcastConfig(M_CONFIGURE_WINDOW, Tmp_win);

	      if (!(Tmp_win->flags & SUPPRESSICON))
		{
		  LowerWindow(Tmp_win);
		  AutoPlace(Tmp_win);
		  if(Tmp_win->Desk == Scr.CurrentDesk)
		    {
                      if(Tmp_win->icon_w)
                        XMapWindow(dpy, Tmp_win->icon_w);
		      if(Tmp_win->icon_pixmap_w != None)
			XMapWindow(dpy, Tmp_win->icon_pixmap_w);
		    }
		}
	      Tmp_win->flags |= ICONIFIED;
	      DrawIconWindow(Tmp_win);
	    }
	}
      break;

    case XA_WM_NORMAL_HINTS:
      GetWindowSizeHints (Tmp_win);
#if 0
      /*
      ** ckh - not sure why this next stuff was here, but fvwm 1.xx
      ** didn't do this, and it seems to cause a bug when changing
      ** fonts in XTerm
      */
      {
	int new_width, new_height;
	new_width = Tmp_win->frame_width;
	new_height = Tmp_win->frame_height;
	ConstrainSize(Tmp_win, &new_width, &new_height, False, 0, 0);
	if((new_width != Tmp_win->frame_width)||
	   (new_height != Tmp_win->frame_height))
	  SetupFrame(Tmp_win,Tmp_win->frame_x, Tmp_win->frame_y,
		     new_width,new_height,False);
      }
#endif /* 0 */
      BroadcastConfig(M_CONFIGURE_WINDOW,Tmp_win);
      break;

    default:
      if(Event.xproperty.atom == _XA_WM_PROTOCOLS)
	FetchWmProtocols (Tmp_win);
      else if (Event.xproperty.atom == _XA_WM_COLORMAP_WINDOWS)
	{
	  FetchWmColormapWindows (Tmp_win);	/* frees old data */
	  ReInstallActiveColormap();
	}
      else if(Event.xproperty.atom == _XA_WM_STATE)
	{
	  if((Tmp_win != NULL)&&(Tmp_win->flags & ClickToFocus)
	     &&(Tmp_win == Scr.Focus))
	    {
              if (OnThisPage)
              {
	        Scr.Focus = NULL;
	        SetFocus(Tmp_win->w,Tmp_win,0);
              }
	    }
	}
      break;
    }
}
예제 #16
0
/***********************************************************************
 *
 *  Procedure:
 *	HandleConfigureRequest - ConfigureRequest event handler
 *
 ************************************************************************/
void HandleConfigureRequest()
{
  XWindowChanges xwc;
  unsigned long xwcm;
  int x, y, width, height;
  XConfigureRequestEvent *cre = &Event.xconfigurerequest;
  Bool sendEvent=False;
  FvwmWindow  *FvwmSib;

  DBUG("HandleConfigureRequest","Routine Entered");

  /*
   * Event.xany.window is Event.xconfigurerequest.parent, so Tmp_win will
   * be wrong
   */
  Event.xany.window = cre->window;	/* mash parent field */
  if (XFindContext (dpy, cre->window, FvwmContext, (caddr_t *) &Tmp_win) ==
      XCNOENT)
    Tmp_win = NULL;

  /*
   * According to the July 27, 1988 ICCCM draft, we should ignore size and
   * position fields in the WM_NORMAL_HINTS property when we map a window.
   * Instead, we'll read the current geometry.  Therefore, we should respond
   * to configuration requests for windows which have never been mapped.
   */
  if (!Tmp_win || cre->window == Tmp_win->icon_w ||
      cre->window == Tmp_win->icon_pixmap_w)
  {

    xwcm = cre->value_mask &
      (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
    xwc.x = cre->x;
    xwc.y = cre->y;
    if((Tmp_win)&&((Tmp_win->icon_pixmap_w == cre->window)))
    {
      Tmp_win->icon_p_height = cre->height+ cre->border_width +
	cre->border_width;
    }
    else if((Tmp_win)&&((Tmp_win->icon_w == cre->window)))
    {
      Tmp_win->icon_xl_loc = cre->x;
      Tmp_win->icon_x_loc = cre->x +
        (Tmp_win->icon_w_width - Tmp_win->icon_p_width)/2;
      Tmp_win->icon_y_loc = cre->y - Tmp_win->icon_p_height;
      if(!(Tmp_win->flags & ICON_UNMAPPED))
        BroadcastPacket(M_ICON_LOCATION, 7,
                        Tmp_win->w, Tmp_win->frame,
                        (unsigned long)Tmp_win,
                        Tmp_win->icon_x_loc, Tmp_win->icon_y_loc,
                        Tmp_win->icon_w_width,
                        Tmp_win->icon_w_height + Tmp_win->icon_p_height);
    }
    xwc.width = cre->width;
    xwc.height = cre->height;
    xwc.border_width = cre->border_width;

    XConfigureWindow(dpy, Event.xany.window, xwcm, &xwc);

    if(Tmp_win)
    {
      if (cre->window != Tmp_win->icon_pixmap_w &&
	  Tmp_win->icon_pixmap_w != None)
      {
	xwc.x = Tmp_win->icon_x_loc;
	xwc.y = Tmp_win->icon_y_loc - Tmp_win->icon_p_height;
	xwcm = cre->value_mask & (CWX | CWY);
	XConfigureWindow(dpy, Tmp_win->icon_pixmap_w, xwcm, &xwc);
      }
      if(Tmp_win->icon_w != None)
      {
	xwc.x = Tmp_win->icon_x_loc;
	xwc.y = Tmp_win->icon_y_loc;
	xwcm = cre->value_mask & (CWX | CWY);
        XConfigureWindow(dpy, Tmp_win->icon_w, xwcm, &xwc);
      }
    }
    return;
  }

  /*  Stacking order change requested...  */
  if (cre->value_mask & CWStackMode)
  {
    FvwmWindow *otherwin;

    otherwin  =  NULL;
    xwc.sibling = (((cre->value_mask & CWSibling) &&
                    (XFindContext (dpy, cre->above, FvwmContext,
                                   (caddr_t *) &otherwin) == XCSUCCESS))
                   ? otherwin->frame : cre->above);
    xwc.stack_mode = cre->detail;
    XConfigureWindow (dpy, Tmp_win->frame,
                      cre->value_mask & (CWSibling | CWStackMode), &xwc);
    sendEvent = True;

    /*
        RBW - Update the stacking order ring.
    */
    if (xwc.stack_mode == Above || xwc.stack_mode == Below)
      {
        FvwmSib = (otherwin != NULL ) ? otherwin: Scr.FvwmRoot.stack_next;  /*  Set up for Above.  */
        if (xwc.stack_mode == Below)
	  {
            /*
                If Below-sibling, raise above next lower window. If no sibling,
                bottom of stack is "above" Scr.FvwmRoot in the ring.
            */
            FvwmSib = (FvwmSib == otherwin) ? FvwmSib->stack_next: FvwmSib->stack_prev;
	  }
        if (Tmp_win != FvwmSib)                            /* Don't chain it to itself!  */
          {
            Tmp_win->stack_prev->stack_next = Tmp_win->stack_next;  /* Pluck from chain.   */
            Tmp_win->stack_next->stack_prev = Tmp_win->stack_prev;
            Tmp_win->stack_next = FvwmSib;                          /* Set new pointers.   */
            Tmp_win->stack_prev = FvwmSib->stack_prev;
            FvwmSib->stack_prev->stack_next = Tmp_win;              /* Re-insert above sibling. */
            FvwmSib->stack_prev = Tmp_win;
          }
      }
    else
      {
        /*
            Oh, bother! We have to rebuild the stacking order ring to figure
            out where this one went (TopIf, BottomIf, or Opposite).
        */
        ResyncFvwmStackRing();
      }
  }

#ifdef SHAPE
  if (ShapesSupported)
  {
    int xws, yws, xbs, ybs;
    unsigned wws, hws, wbs, hbs;
    int boundingShaped, clipShaped;

    XShapeQueryExtents (dpy, Tmp_win->w,&boundingShaped, &xws, &yws, &wws,
			&hws,&clipShaped, &xbs, &ybs, &wbs, &hbs);
    Tmp_win->wShaped = boundingShaped;
  }
#endif /* SHAPE */

  /* Don't modify frame_XXX fields before calling SetupWindow! */
  x = Tmp_win->frame_x;
  y = Tmp_win->frame_y;
  width = Tmp_win->frame_width;
  height = Tmp_win->frame_height;

  /* for restoring */
  if (cre->value_mask & CWBorderWidth)
  {
    Tmp_win->old_bw = cre->border_width;
  }
  /* override even if border change */

  if (cre->value_mask & CWX)
    x = cre->x - Tmp_win->boundary_width - Tmp_win->bw;
  if (cre->value_mask & CWY)
    y = cre->y - Tmp_win->boundary_width - Tmp_win->title_height - Tmp_win->bw;
  if (cre->value_mask & CWWidth)
    width = cre->width + 2*Tmp_win->boundary_width;
  if (cre->value_mask & CWHeight)
    height = cre->height+Tmp_win->title_height+2*Tmp_win->boundary_width;

  /*
   * SetupWindow (x,y) are the location of the upper-left outer corner and
   * are passed directly to XMoveResizeWindow (frame).  The (width,height)
   * are the inner size of the frame.  The inner width is the same as the
   * requested client window width; the inner height is the same as the
   * requested client window height plus any title bar slop.
   */
  ConstrainSize(Tmp_win, &width, &height, False, 0, 0);
  SetupFrame (Tmp_win, x, y, width, height,sendEvent);
  KeepOnTop();
}