/** 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); }
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); } }
/** 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); }
/** 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); } } }
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); } }
/* * 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; }
/** *** 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); } }
/** 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; }
/** 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); } }
/** 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(); }
/** 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(); }
/** 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; }
/* * 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; }
/** 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); } }
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; } }
/*********************************************************************** * * 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(); }