Revert full screen, maximized and minimized code (rev 16543).

Revert this because don't work "fine" with dual-monitor.

The problem is not the code, this work fine, but full screen
for a window manager is not both monitor (until set xinerama or
whatever..).
This commit is contained in:
Diego Borghetti 2008-09-22 19:09:46 +00:00
parent 48c54c275b
commit 4e731c5ab5
4 changed files with 65 additions and 386 deletions

@ -96,25 +96,17 @@ GHOST_SystemX11(
if (!m_display) return;
#ifdef __sgi
m_delete_window_atom = XSGIFastInternAtom(m_display,
m_delete_window_atom
= XSGIFastInternAtom(m_display,
"WM_DELETE_WINDOW",
SGI_XA_WM_DELETE_WINDOW, False);
#else
m_delete_window_atom = XInternAtom(m_display, "WM_DELETE_WINDOW", False);
m_delete_window_atom
= XInternAtom(m_display, "WM_DELETE_WINDOW", True);
#endif
m_wm_protocols= XInternAtom(m_display, "WM_PROTOCOLS", False);
m_wm_take_focus= XInternAtom(m_display, "WM_TAKE_FOCUS", False);
m_wm_state= XInternAtom(m_display, "WM_STATE", False);
m_wm_change_state= XInternAtom(m_display, "WM_CHANGE_STATE", False);
m_net_state= XInternAtom(m_display, "_NET_WM_STATE", False);
m_net_max_horz= XInternAtom(m_display,
"_NET_WM_STATE_MAXIMIZED_HORZ", False);
m_net_max_vert= XInternAtom(m_display,
"_NET_WM_STATE_MAXIMIZED_VERT", False);
m_net_fullscreen= XInternAtom(m_display,
"_NET_WM_STATE_FULLSCREEN", False);
m_motif= XInternAtom(m_display, "_MOTIF_WM_HINTS", False);
// compute the initial time
timeval tv;
@ -522,12 +514,10 @@ GHOST_SystemX11::processEvent(XEvent *xe)
GHOST_kEventNDOFButton,
window, data);
}
}
else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
} else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
/* as ICCCM say, we need reply this event
* with a SetInputFocus, the data[1] have
* the valid timestamp (send by the window
* manager).
* the valid timestamp (send by the wm).
*/
XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
} else {
@ -547,24 +537,6 @@ GHOST_SystemX11::processEvent(XEvent *xe)
// XCrossingEvents pointer leave enter window.
break;
case MapNotify:
/*
* From ICCCM:
* [ Clients can select for StructureNotify on their
* top-level windows to track transition between
* Normal and Iconic states. Receipt of a MapNotify
* event will indicate a transition to the Normal
* state, and receipt of an UnmapNotify event will
* indicate a transition to the Iconic state. ]
*/
if (window->m_post_init == True) {
/*
* Now we are sure that the window is
* mapped, so only need change the state.
*/
window->setState(window->m_post_state);
window->m_post_init= False;
}
break;
case UnmapNotify:
break;
case MappingNotify:

@ -215,21 +215,9 @@ public:
*/
virtual void putClipboard(GHOST_TInt8 *buffer, int flag) const;
/**
* Atom used for ICCCM, WM-spec and Motif.
* We only need get this atom at the start, it's relative
* to the display not the window and are public for every
* window that need it.
*/
Atom m_wm_protocols;
/* Atom used for ICCCM. */
Atom m_wm_take_focus;
Atom m_wm_state;
Atom m_wm_change_state;
Atom m_net_state;
Atom m_net_max_horz;
Atom m_net_max_vert;
Atom m_net_fullscreen;
Atom m_motif;
Atom m_wm_protocols;
Atom m_delete_window_atom;
private :

@ -54,16 +54,6 @@ typedef struct {
#define MWM_HINTS_DECORATIONS (1L << 1)
/*
* A client can't change the window property, that is the
* work of the window manager. We send a ClientMessage
* event to the Root window with the property
* and the Action (WM-spec define this):
*/
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2
/*
import bpy
I = bpy.data.images['blender.png'] # the 48x48 icon
@ -164,10 +154,10 @@ GHOST_WindowX11(
// Set up the minimum atrributes that we require and see if
// X can find us a visual matching those requirements.
int attributes[40], i = 0;
Atom atoms[2];
int natom;
int attributes[40], i = 0;
if(m_stereoVisual)
attributes[i++] = GLX_STEREO;
@ -272,24 +262,44 @@ GHOST_WindowX11(
// Are we in fullscreen mode - then include
// some obscure blut code to remove decorations.
/*
* One of the problem with WM_spec is that can't set a property
* to a window that isn't mapped. That is why we can't "just
* call setState" here.
*
* To fix this, we first need know that the window is really
* mapped waiting for the MapNotify event.
*
* So, m_post_init indicate that we need wait for the MapNotify
* event and then set the window state to the m_post_state.
*/
if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
m_post_init = True;
m_post_state = state;
if (state == GHOST_kWindowStateFullScreen) {
MotifWmHints hints;
Atom atom;
atom = XInternAtom(m_display, "_MOTIF_WM_HINTS", False);
if (atom == None) {
GHOST_PRINT("Could not intern X atom for _MOTIF_WM_HINTS.\n");
} else {
hints.flags = MWM_HINTS_DECORATIONS;
hints.decorations = 0; /* Absolutely no decorations. */
// other hints.decorations make no sense
// you can't select individual decorations
XChangeProperty(m_display, m_window,
atom, atom, 32,
PropModeReplace, (unsigned char *) &hints, 4);
}
} else if (state == GHOST_kWindowStateMaximized) {
// With this, xprop should report the following just after launch
// _NET_WM_STATE(ATOM) = _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ
// After demaximization the right side is empty, though (maybe not the most correct then?)
Atom state, atomh, atomv;
state = XInternAtom(m_display, "_NET_WM_STATE", False);
atomh = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
atomv = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
if (state == None ) {
GHOST_PRINT("Atom _NET_WM_STATE requested but not avaliable nor created.\n");
} else {
XChangeProperty(m_display, m_window,
state, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &atomh, 1);
XChangeProperty(m_display, m_window,
state, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &atomv, 1);
}
else {
m_post_init = False;
m_post_state = GHOST_kWindowStateNormal;
}
// Create some hints for the window manager on how
@ -654,298 +664,28 @@ clientToScreen(
outY = ay;
}
void GHOST_WindowX11::icccmSetState(int state)
{
XEvent xev;
if (state != IconicState)
return;
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.display = m_display;
xev.xclient.window = m_window;
xev.xclient.format = 32;
xev.xclient.message_type = m_system->m_wm_change_state;
xev.xclient.data.l[0] = state;
XSendEvent (m_display, RootWindow(m_display, DefaultScreen(m_display)),
False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
GHOST_TWindowState
GHOST_WindowX11::
getState(
) const {
//FIXME
return GHOST_kWindowStateNormal;
}
int GHOST_WindowX11::icccmGetState(void) const
{
unsigned char *prop_ret;
unsigned long bytes_after, num_ret;
Atom type_ret;
int format_ret, st;
GHOST_TSuccess
GHOST_WindowX11::
setState(
GHOST_TWindowState state
){
//TODO
prop_ret = NULL;
st = XGetWindowProperty(m_display, m_window, m_system->m_wm_state, 0,
0x7fffffff, False, m_system->m_wm_state, &type_ret,
&format_ret, &num_ret, &bytes_after, &prop_ret);
if ((st == Success) && (prop_ret) && (num_ret == 2))
st = prop_ret[0];
else
st = NormalState;
if (prop_ret)
XFree(prop_ret);
return (st);
}
void GHOST_WindowX11::netwmMaximized(bool set)
{
XEvent xev;
xev.xclient.type= ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = m_window;
xev.xclient.message_type = m_system->m_net_state;
xev.xclient.format = 32;
if (set == True)
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
else
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = m_system->m_net_max_horz;
xev.xclient.data.l[2] = m_system->m_net_max_vert;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
XSendEvent (m_display, RootWindow(m_display, DefaultScreen(m_display)),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
bool GHOST_WindowX11::netwmIsMaximized(void) const
{
unsigned char *prop_ret;
unsigned long bytes_after, num_ret, i;
Atom type_ret;
bool st;
int format_ret, count;
prop_ret = NULL;
st = False;
i = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
&num_ret, &bytes_after, &prop_ret);
if ((i == Success) && (prop_ret) && (format_ret == 32)) {
count = 0;
for (i = 0; i < num_ret; i++) {
if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_horz)
count++;
if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_vert)
count++;
if (count == 2) {
st = True;
break;
}
}
}
if (prop_ret)
XFree(prop_ret);
return (st);
}
void GHOST_WindowX11::netwmFullScreen(bool set)
{
XEvent xev;
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = m_window;
xev.xclient.message_type = m_system->m_net_state;
xev.xclient.format = 32;
if (set == True)
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
else
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = m_system->m_net_fullscreen;
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
XSendEvent (m_display, RootWindow(m_display, DefaultScreen(m_display)),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
bool GHOST_WindowX11::netwmIsFullScreen(void) const
{
unsigned char *prop_ret;
unsigned long bytes_after, num_ret, i;
Atom type_ret;
bool st;
int format_ret;
prop_ret = NULL;
st = False;
i = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
&num_ret, &bytes_after, &prop_ret);
if ((i == Success) && (prop_ret) && (format_ret == 32)) {
for (i = 0; i < num_ret; i++) {
if (((unsigned long *)prop_ret)[i] == m_system->m_net_fullscreen) {
st = True;
break;
}
}
}
if (prop_ret)
XFree(prop_ret);
return (st);
}
void GHOST_WindowX11::motifFullScreen(bool set)
{
MotifWmHints hints;
hints.flags = MWM_HINTS_DECORATIONS;
if (set == True)
hints.decorations = 0;
else
hints.decorations = 1;
XChangeProperty(m_display, m_window, m_system->m_motif,
m_system->m_motif, 32, PropModeReplace,
(unsigned char *)&hints, 4);
}
bool GHOST_WindowX11::motifIsFullScreen(void) const
{
unsigned char *prop_ret;
unsigned long bytes_after, num_ret;
MotifWmHints *hints;
Atom type_ret;
bool state;
int format_ret, st;
prop_ret = NULL;
state = False;
st = XGetWindowProperty(m_display, m_window, m_system->m_motif, 0,
0x7fffffff, False, m_system->m_motif,
&type_ret, &format_ret, &num_ret,
&bytes_after, &prop_ret);
if ((st == Success) && (prop_ret)) {
hints = (MotifWmHints *)prop_ret;
if (hints->flags & MWM_HINTS_DECORATIONS) {
if (!hints->decorations)
state = True;
}
}
if (prop_ret)
XFree(prop_ret);
return (state);
}
GHOST_TWindowState GHOST_WindowX11::getState() const
{
GHOST_TWindowState state_ret;
int state;
state_ret = GHOST_kWindowStateNormal;
state = icccmGetState();
/*
* In the Iconic and Withdrawn state, the window is
* unmaped, so only need return a Minimized state.
*/
if ((state == IconicState) || (state == WithdrawnState))
state_ret = GHOST_kWindowStateMinimized;
else if (netwmIsMaximized() == True)
state_ret = GHOST_kWindowStateMaximized;
else if (netwmIsFullScreen() == True)
state_ret = GHOST_kWindowStateFullScreen;
else if (motifIsFullScreen() == True)
state_ret = GHOST_kWindowStateFullScreen;
return (state_ret);
}
GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
{
GHOST_TWindowState cur_state;
bool is_max, is_full, is_motif_full;
cur_state = getState();
if (state == (int)cur_state)
if (state == (int)getState()) {
return GHOST_kSuccess;
if (cur_state != GHOST_kWindowStateMinimized) {
/*
* The window don't have this property's
* if it's not mapped.
*/
is_max = netwmIsMaximized();
is_full = netwmIsFullScreen();
}
else {
is_max = False;
is_full = False;
} else {
return GHOST_kFailure;
}
is_motif_full = motifIsFullScreen();
if (state == GHOST_kWindowStateNormal) {
if (is_max == True)
netwmMaximized(False);
if (is_full == True)
netwmFullScreen(False);
if (is_motif_full == True)
motifFullScreen(False);
icccmSetState(NormalState);
return (GHOST_kSuccess);
}
if (state == GHOST_kWindowStateFullScreen) {
/*
* We can't change to full screen if the window
* isn't mapped.
*/
if (cur_state == GHOST_kWindowStateMinimized)
return (GHOST_kFailure);
if (is_max == True)
netwmMaximized(False);
if (is_full == False)
netwmFullScreen(True);
if (is_motif_full == False)
motifFullScreen(True);
return (GHOST_kSuccess);
}
if (state == GHOST_kWindowStateMaximized) {
/*
* We can't change to Maximized if the window
* isn't mapped.
*/
if (cur_state == GHOST_kWindowStateMinimized)
return (GHOST_kFailure);
if (is_full == True)
netwmFullScreen(False);
if (is_motif_full == True)
motifFullScreen(False);
if (is_max == False)
netwmMaximized(True);
return (GHOST_kSuccess);
}
if (state == GHOST_kWindowStateMinimized) {
/*
* The window manager need save the current state of
* the window (maximized, full screen, etc).
*/
icccmSetState(IconicState);
return (GHOST_kSuccess);
}
return (GHOST_kFailure);
}
#include <iostream>

@ -212,15 +212,6 @@ public:
const GHOST_TabletData* GetTabletData()
{ return &m_xtablet.CommonData; }
/*
* Need this in case that we want start the window
* in FullScreen or Maximized state.
* Check GHOST_WindowX11.cpp
*/
bool m_post_init;
GHOST_TWindowState m_post_state;
protected:
/**
* Tries to install a rendering context in this window.
@ -336,18 +327,6 @@ private :
/* Tablet devices */
XTablet m_xtablet;
void icccmSetState(int state);
int icccmGetState() const;
void netwmMaximized(bool set);
bool netwmIsMaximized() const;
void netwmFullScreen(bool set);
bool netwmIsFullScreen() const;
void motifFullScreen(bool set);
bool motifIsFullScreen() const;
};