procedure TFPWMClient.focusIfAppropriate(ifActive: Boolean);
var
  rw, cw: TWindow;
  rx, ry, cx, cy: cint;
  k: cuint;
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.focusIfAppropriate]');
  {$endif}
    if not CONFIG_AUTO_RAISE then Exit();
    if (not m_managed) or (not isNormal()) then Exit();
    if (not ifActive) and isActive() then Exit();
    XQueryPointer(display(), root(), @rw, @cw, @rx, @ry, @cx, @cy, @k);
    if (hasWindow(cw)) then
    begin
	activate();
	mapRaised();
	m_windowManager.stopConsideringFocus();
    end;
end;
procedure TFPWMClient.eventConfigureRequest(e: PXConfigureRequestEvent);
var
  wc: TXWindowChanges;
  raise_: Boolean = False;
  popTime: x.TTime;
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventConfigureRequest]');
  {$endif}
    e^.value_mask := e^.value_mask and not CWSibling;
    gravitate(True);
    if (e^.value_mask and CWX) <> 0 then m_x := e^.x;
    if (e^.value_mask and CWY) <> 0 then m_y := e^.y;
    if (e^.value_mask and CWWidth) <> 0 then m_w := e^.width;
    if (e^.value_mask and CWHeight) <> 0 then m_h := e^.height;
    if (e^.value_mask and CWBorderWidth) <> 0 then m_bw := e^.border_width;
    gravitate(False);
    if (e^.value_mask and CWStackMode) <> 0 then
    begin
	if (e^.detail = Above) then raise_ := True;
	e^.value_mask := e^.value_mask and not CWStackMode;
    end;
    if (parent() <> root()) and (m_window = e^.window) then
    begin
	m_border.configure(m_x, m_y, m_w, m_h, e^.value_mask, e^.detail);
	sendConfigureNotify();
    end;
    if (m_managed) then
    begin
	wc.x := m_border.xIndent();
	wc.y := m_border.yIndent();
    end
    else
    begin
	wc.x := e^.x;
	wc.y := e^.y;
    end;
    wc.width := e^.width;
    wc.height := e^.height;
    wc.border_width := 0;
    wc.sibling := None;
    wc.stack_mode := Above;
    e^.value_mask := e^.value_mask and not CWStackMode;
    e^.value_mask := e^.value_mask or CWBorderWidth;
    XConfigureWindow(display(), e^.window, e^.value_mask, @wc);
    if raise_ and (parent() <> root()) then
    begin
	if (CONFIG_AUTO_RAISE) then
        begin
	    m_windowManager.stopConsideringFocus();
	    if (not m_stubborn) then 
	    begin
               popTime := windowManager.timestamp(True);
		if (m_lastPopTime > 0) and
		    (popTime > m_lastPopTime) and
		    (popTime - m_lastPopTime < 2000) then 
		begin
                    m_stubborn := True;
                    m_lastPopTime := 0;
		end
                else
		    m_lastPopTime := popTime;
		mapRaised();
            end;
	end
        else
        begin
	    mapRaised();
	    if (CONFIG_CLICK_TO_FOCUS) then activate();
	end;
    end;
end;
procedure TFPWMClient.eventMapRequest(e: PXMapRequestEvent);
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventMapRequest]');
  {$endif}
    case m_state of
    WithdrawnState:
    begin
        if (parent() = root()) then
        begin
	    manage(False);
	    Exit;
	end;
	m_border.reparent();
	if (CONFIG_AUTO_RAISE) then m_windowManager.stopConsideringFocus();
	XAddToSaveSet(display(), m_window);
	XMapWindow(display(), m_window);
	mapRaised();
	setState(NormalState);
	if (CONFIG_CLICK_TO_FOCUS) then activate();
    end;
    NormalState:
    begin
	XMapWindow(display(), m_window);
	mapRaised();
	if (CONFIG_CLICK_TO_FOCUS) then activate();
    end;
    IconicState:
    begin
	if (CONFIG_AUTO_RAISE) then m_windowManager.stopConsideringFocus();
	unhide(True);
    end;
    end;
end;
procedure TFPWMClient.eventUnmap(e: PXUnmapEvent);
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventUnmap]');
  {$endif}
    case m_state of
    IconicState:
    begin
	if (e^.send_event) <> 0 then
        begin
	    unhide(False);
	    withdraw();
	end;
    end;
    NormalState:
    begin
	if (isActive()) then m_windowManager.clearFocus();
	if (not m_reparenting) then withdraw();
    end;
    end;
    m_reparenting := False;
    m_stubborn := False;
end;
procedure TFPWMClient.eventColormap(e: PXColormapEvent);
var
  i: Integer;
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventColormap]');
  {$endif}
    if (e^.window = m_window) or (e^.window = parent()) then
    begin
	m_colormap := e^.colormap;
	if (isActive()) then installColormap();
    end
    else
    begin
	for i := 0 to m_colormapWinCount - 1 do
        begin
	    if (m_colormapWindows[i] = e^.window) then
            begin
		m_windowColormaps[i] := e^.colormap;
		if (isActive()) then installColormap();
		Exit;
	    end;
	end;
    end;
end;
procedure TFPWMClient.eventProperty(e: PXPropertyEvent);
var
  a: TAtom;
  shouldDelete: Boolean;
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventProperty]');
  {$endif}
    a := e^.atom;
    shouldDelete := (e^.state = PropertyDelete);
    case a of
    XA_WM_ICON_NAME:
    begin
        if shouldDelete then m_iconName := ''
        else m_iconName := getProperty(a);
        if (setLabel()) then rename();
    end;
    XA_WM_NAME:
    begin
        if shouldDelete then m_name := ''
        else m_name := getProperty(a);
	if (setLabel()) then rename();
    end;
    XA_WM_TRANSIENT_FOR:
    begin
	getTransient();
	Exit;
    end;
    end;
    if (a = Atoms.wm_colormaps) then
    begin
	getColormaps();
	if (isActive()) then installColormap();
    end;
end;
procedure TFPWMClient.eventEnter(e: PXCrossingEvent);
var
  x, y: cint;
  c: TWindow;
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventEnter]');
  {$endif}
    if (not isActive()) and (activeClient() <> nil) and (activeClient().isNormal()) and
	(not activeClient().isTransient()) then
    begin
	XTranslateCoordinates
	    (display(), activeClient().parent(), e^.window, 0, 0, @x, @y, @c);
	if (activeClient().coordsInHole(e^.x - x, e^.y - y)) then Exit;
    end;
    if (e^._type = EnterNotify) then
    begin
	if (not isActive()) and (not CONFIG_CLICK_TO_FOCUS) then
        begin
	    activate();
	    if (CONFIG_AUTO_RAISE) then
		windowManager().considerFocusChange(Self, m_window, e^.time)
	    else if (CONFIG_RAISE_ON_FOCUS) then
		mapRaised();
       end;
    end;
end;
function TFPWMClient.coordsInHole(x, y: cint): Boolean;	
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.coordsInHole]');
  {$endif}
  Result := m_border.coordsInHole(x, y);
end;
procedure TFPWMClient.eventFocusIn(e: PXFocusInEvent);
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventFocusIn]');
  {$endif}
    if (m_window = e^.window) and (not isActive()) then
    begin
	activate();
	mapRaised();
    end;
end;
procedure TFPWMClient.eventExposure(e: PXExposeEvent);
begin
  {$ifdef FPWM_TRACE}
  FPWMTrace('[TFPWMClient.eventExposure]');
  {$endif}
    if (m_border.hasWindow(e^.window)) then
	m_border.expose_(e);
end;
