Generalize selection handling. Manage _NET_WM_CM_Sx selection.

- Should fix issues with recent gtk ARGB windows.


SVN revision: 25746
This commit is contained in:
Kim Woelders 2006-09-11 18:10:28 +00:00
parent 5a11c09141
commit 6cf576336f
5 changed files with 120 additions and 37 deletions

View File

@ -671,6 +671,7 @@ void EdgeWindowsHide(void);
#define EDBUG_TYPE_VERBOSE 144
#define EDBUG_TYPE_SYNC 145
#define EDBUG_TYPE_PAGER 146
#define EDBUG_TYPE_SELECTION 147
int EventDebug(unsigned int type);
void EventDebugSet(unsigned int type, int value);

View File

@ -33,6 +33,7 @@
#include "ecompmgr.h"
#include "emodule.h"
#include "eobj.h"
#include "hints.h"
#include "settings.h"
#include "timers.h"
#include "xwin.h"
@ -190,6 +191,8 @@ static Picture rootBuffer;
static XserverRegion allDamage;
static ESelection *wm_cm_sel = NULL;
#define OPAQUE 0xffffffff
#define OP32(op) ((double)(op)/OPAQUE)
@ -2290,6 +2293,8 @@ ECompMgrStart(void)
EventCallbackRegister(VRoot.win, 0, ECompMgrHandleRootEvent, NULL);
wm_cm_sel = SelectionAcquire("_NET_WM_CM_S", NULL, NULL);
lst = EobjListStackGet(&num);
for (i = 0; i < num; i++)
{
@ -2318,6 +2323,9 @@ ECompMgrStop(void)
EGrabServer();
SelectionRelease(wm_cm_sel);
wm_cm_sel = NULL;
if (rootPicture)
XRenderFreePicture(disp, rootPicture);
rootPicture = None;

View File

@ -33,6 +33,8 @@
#include <X11/Xatom.h>
/* Misc atoms */
Atom E_XA_MANAGER = 0;
Atom E_XROOTPMAP_ID;
Atom E_XROOTCOLOR_PIXEL;
@ -42,16 +44,14 @@ static Ecore_X_Atom ENL_INTERNAL_DESK_DATA;
static Ecore_X_Atom ENL_WIN_DATA;
static Ecore_X_Atom ENL_WIN_BORDER;
/*
* Functions that set X11-properties from E-internals
*/
void
HintsInit(void)
{
Atom atom;
Window win;
E_XA_MANAGER = XInternAtom(disp, "MANAGER", False);
E_XROOTPMAP_ID = XInternAtom(disp, "_XROOTPMAP_ID", False);
E_XROOTCOLOR_PIXEL = XInternAtom(disp, "_XROOTCOLOR_PIXEL", False);
@ -81,6 +81,10 @@ HintsInit(void)
Mode.root.ext_pmap_valid = EDrawableCheck(Mode.root.ext_pmap, 0);
}
/*
* Functions that set X11-properties from E-internals
*/
void
HintsSetRootHints(Win win __UNUSED__)
{
@ -493,3 +497,81 @@ EHintsSetInfoOnAll(void)
EHintsSetDeskInfo();
}
/*
* Selections.
*/
struct _selection
{
Atom atom;
Time time;
Win win;
EventCallbackFunc *func;
void *data;
};
ESelection *
SelectionAcquire(const char *name, EventCallbackFunc * func, void *data)
{
ESelection *sel;
char buf[128];
sel = Ecalloc(1, sizeof(ESelection));
if (!sel)
return sel;
Esnprintf(buf, sizeof(buf), "%s%d", name, VRoot.scr);
sel->atom = XInternAtom(disp, buf, False);
sel->time = EGetTimestamp();
sel->win = ECreateEventWindow(VRoot.win, -100, -100, 1, 1);
sel->func = func;
sel->data = data;
XSetSelectionOwner(disp, sel->atom, WinGetXwin(sel->win), sel->time);
if (XGetSelectionOwner(disp, sel->atom) != WinGetXwin(sel->win))
{
DialogOK(_("ERROR!"), _("Could not acquire selection: %s"), buf);
EDestroyWindow(sel->win);
Efree(sel);
return NULL;
}
if (sel->func)
{
ESelectInput(sel->win,
SubstructureRedirectMask | SubstructureNotifyMask);
EventCallbackRegister(sel->win, 0, sel->func, sel->data);
}
ecore_x_client_message32_send(VRoot.xwin, E_XA_MANAGER,
StructureNotifyMask, CurrentTime, sel->atom,
WinGetXwin(sel->win), 0, 0);
if (EventDebug(EDBUG_TYPE_SELECTION))
Eprintf("Window %#lx is now %s owner, time=%lu\n",
WinGetXwin(sel->win), buf, sel->time);
return sel;
}
void
SelectionRelease(ESelection * sel)
{
if (!sel)
return;
if (EventDebug(EDBUG_TYPE_SELECTION))
Eprintf("Window %#lx is no longer %s owner\n",
WinGetXwin(sel->win), XGetAtomName(disp, sel->atom));
XSetSelectionOwner(disp, sel->atom, None, sel->time);
if (sel->func)
{
EventCallbackUnregister(sel->win, 0, sel->func, sel->data);
}
EDestroyWindow(sel->win);
Efree(sel);
}

View File

@ -25,6 +25,8 @@
#define _HINTS_H_
/* Misc atoms */
extern Atom E_XA_MANAGER;
extern Atom E_XROOTPMAP_ID;
extern Atom E_XROOTCOLOR_PIXEL;
@ -101,6 +103,11 @@ void EHintsSetDeskInfo(void);
void EHintsGetDeskInfo(void);
void EHintsSetInfoOnAll(void);
typedef struct _selection ESelection;
ESelection *SelectionAcquire(const char *name, EventCallbackFunc * func,
void *data);
void SelectionRelease(ESelection * sel);
/* icccm.c */
void ICCCM_Init(void);
void ICCCM_ProcessClientMessage(XClientMessageEvent * event);

View File

@ -23,6 +23,7 @@
#include "E.h"
#include "container.h"
#include "e16-ecore_hints.h"
#include "hints.h"
#include "xwin.h"
#define DEBUG_SYSTRAY 0
@ -37,19 +38,16 @@ typedef struct
#define StObjGetWin(o) (((SWin*)(o))->win)
#define StObjIsMapped(o) (((SWin*)(o))->mapped)
/* Selection atoms */
static Atom E_XA_MANAGER = 0;
/* XEmbed atoms */
static Atom E_XA__XEMBED = 0;
static Atom E_XA__XEMBED_INFO = 0;
/* Systray atoms */
static Atom _NET_SYSTEM_TRAY_Sx = 0;
static Atom _NET_SYSTEM_TRAY_OPCODE = 0;
static Atom _NET_SYSTEM_TRAY_MESSAGE_DATA = 0;
static Win systray_sel_win = NoWin;
static Time systray_sel_time = 0;
/* Systray selection */
static ESelection *systray_sel = NULL;
static void SystrayItemEvent(Win win, XEvent * ev, void *prm);
@ -328,6 +326,12 @@ SystraySelectionEvent(Win win __UNUSED__, XEvent * ev, void *prm)
ev->xany.window);
break;
case SelectionClear:
DialogOK(_("Systray Error!"), _("Systray went elsewhere?!?"));
SelectionRelease(systray_sel);
systray_sel = None;
break;
case ClientMessage:
SystrayEventClientMessage(prm, &(ev->xclient));
break;
@ -417,51 +421,33 @@ SystrayInit(Container * ct)
Esnprintf(buf, sizeof(buf), "_NET_SYSTEM_TRAY_S%d", VRoot.scr);
E_XA_MANAGER = XInternAtom(disp, "MANAGER", False);
E_XA__XEMBED = XInternAtom(disp, "_XEMBED", False);
E_XA__XEMBED_INFO = XInternAtom(disp, "_XEMBED_INFO", False);
_NET_SYSTEM_TRAY_Sx = XInternAtom(disp, buf, False);
_NET_SYSTEM_TRAY_OPCODE =
XInternAtom(disp, "_NET_SYSTEM_TRAY_OPCODE", False);
_NET_SYSTEM_TRAY_MESSAGE_DATA =
XInternAtom(disp, "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
/* Acquire selection */
if (systray_sel_win != None)
if (systray_sel)
{
DialogOK(_("Systray Error!"), _("Only one systray is allowed"));
return;
}
systray_sel_win = ECreateEventWindow(VRoot.win, -100, -100, 1, 1);
systray_sel_time = EGetTimestamp();
XSetSelectionOwner(disp, _NET_SYSTEM_TRAY_Sx, WinGetXwin(systray_sel_win),
systray_sel_time);
if (XGetSelectionOwner(disp, _NET_SYSTEM_TRAY_Sx) !=
WinGetXwin(systray_sel_win))
systray_sel =
SelectionAcquire("_NET_SYSTEM_TRAY_S", SystraySelectionEvent, ct);
if (!systray_sel)
{
DialogOK(_("Systray Error!"), _("Could not activate systray"));
Eprintf("Failed to acquire selection %s\n", buf);
EDestroyWindow(systray_sel_win);
systray_sel_win = None;
return;
}
if (EventDebug(EDBUG_TYPE_ICONBOX))
Eprintf("Window %#lx is now %s owner, time=%ld\n",
WinGetXwin(systray_sel_win), buf, systray_sel_time);
ESelectInput(systray_sel_win,
SubstructureRedirectMask | SubstructureNotifyMask);
EventCallbackRegister(systray_sel_win, 0, SystraySelectionEvent, ct);
win = ct->icon_win;
ESelectInputAdd(win,
SubstructureRedirectMask /* | SubstructureNotifyMask */ );
EventCallbackRegister(win, 0, SystrayEvent, ct);
ecore_x_client_message32_send(VRoot.xwin, E_XA_MANAGER, StructureNotifyMask,
CurrentTime, _NET_SYSTEM_TRAY_Sx,
WinGetXwin(systray_sel_win), 0, 0);
/* Container parameter setup */
ct->wm_name = "Systray";
ct->menu_title = _("Systray Options");
@ -472,11 +458,10 @@ SystrayInit(Container * ct)
static void
SystrayExit(Container * ct, int wm_exit __UNUSED__)
{
XSetSelectionOwner(disp, _NET_SYSTEM_TRAY_Sx, None, systray_sel_time);
EventCallbackUnregister(systray_sel_win, 0, SystraySelectionEvent, ct);
SelectionRelease(systray_sel);
systray_sel = None;
EventCallbackUnregister(ct->win, 0, SystrayEvent, ct);
EDestroyWindow(systray_sel_win);
systray_sel_win = None;
while (ct->num_objs)
{