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:
parent
5a11c09141
commit
6cf576336f
1
src/E.h
1
src/E.h
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
90
src/hints.c
90
src/hints.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue