mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Importing EDE2 code to svn... NOTE: It doesn't compile! Stuff thats broken: edewm, eworkpanel, eiconman,
emenueditor
This commit is contained in:
508
edewm/Events.cpp
Normal file
508
edewm/Events.cpp
Normal file
@ -0,0 +1,508 @@
|
||||
/*
|
||||
* $Id: Events.cpp 1712 2006-07-25 10:04:41Z karijes $
|
||||
*
|
||||
* Edewm, window manager
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "Events.h"
|
||||
#include "Frame.h"
|
||||
#include "Titlebar.h"
|
||||
#include "Windowmanager.h"
|
||||
#include "Tracers.h"
|
||||
#include "Atoms.h"
|
||||
#include "Hints.h"
|
||||
#include "Cursor.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#define FRAME_NAME(frame) (frame->label ? frame->label : "NULL")
|
||||
|
||||
FrameEventHandler::FrameEventHandler(Frame* f) : curr_frame(f)
|
||||
{
|
||||
assert(curr_frame != NULL);
|
||||
}
|
||||
|
||||
FrameEventHandler::~FrameEventHandler()
|
||||
{
|
||||
}
|
||||
|
||||
/* Handle efltk events.
|
||||
* Some events like FL_FOCUS and FL_UNFOCUS are not handled, since
|
||||
* efltk does not receive this event when when should (for example:
|
||||
* one window is focused, but other shoud be automatically unfocused).
|
||||
* X on ther hand send FocusIn and FocusOut when above events ocurr.
|
||||
*/
|
||||
int FrameEventHandler::handle_fltk(int event)
|
||||
{
|
||||
long gggg;
|
||||
static long bbbb;
|
||||
static CursorType ctype;
|
||||
|
||||
if(curr_frame->show_titlebar)
|
||||
{
|
||||
Titlebar* tbar = curr_frame->titlebar;
|
||||
assert(tbar != NULL);
|
||||
|
||||
if(!curr_frame->resizing())
|
||||
{
|
||||
if(Fl::event_inside(tbar->x(), tbar->y(), tbar->w(), tbar->h()) || curr_frame->moving())
|
||||
return tbar->handle(event);
|
||||
}
|
||||
}
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case FL_SHOW:
|
||||
case FL_HIDE:
|
||||
return 0;
|
||||
|
||||
case FL_ENTER:
|
||||
ELOG("FrameEventHandler: FL_ENTER");
|
||||
return 1;
|
||||
|
||||
case FL_LEAVE:
|
||||
ELOG("FrameEventHandler: FL_LEAVE");
|
||||
return 1;
|
||||
|
||||
case FL_MOVE:
|
||||
{
|
||||
// note, I am using coordinates _inside_ window
|
||||
gggg = curr_frame->resize_type(Fl::event_x(), Fl::event_y());
|
||||
switch(gggg)
|
||||
{
|
||||
case ResizeTypeUpLeft:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeUpLeft");
|
||||
curr_frame->set_cursor(CURSOR_NW);
|
||||
ctype = CURSOR_NW;
|
||||
bbbb = ResizeTypeUpLeft;
|
||||
return 1;
|
||||
case ResizeTypeUpRight:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeUpRight");
|
||||
curr_frame->set_cursor(CURSOR_NE);
|
||||
ctype = CURSOR_NE;
|
||||
bbbb = ResizeTypeUpRight;
|
||||
return 1;
|
||||
case ResizeTypeDownLeft:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeDownLeft");
|
||||
curr_frame->set_cursor(CURSOR_SW);
|
||||
ctype = CURSOR_SW;
|
||||
bbbb = ResizeTypeDownLeft;
|
||||
return 1;
|
||||
case ResizeTypeDownRight:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeDownRight");
|
||||
curr_frame->set_cursor(CURSOR_SE);
|
||||
ctype = CURSOR_SE;
|
||||
bbbb = ResizeTypeDownRight;
|
||||
return 1;
|
||||
case ResizeTypeUp:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeUp");
|
||||
curr_frame->set_cursor(CURSOR_N);
|
||||
ctype = CURSOR_N;
|
||||
bbbb = ResizeTypeUp;
|
||||
return 1;
|
||||
case ResizeTypeLeft:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeLeft");
|
||||
curr_frame->set_cursor(CURSOR_W);
|
||||
ctype = CURSOR_W;
|
||||
bbbb = ResizeTypeLeft;
|
||||
return 1;
|
||||
case ResizeTypeRight:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeRight");
|
||||
curr_frame->set_cursor(CURSOR_E);
|
||||
ctype = CURSOR_E;
|
||||
bbbb = ResizeTypeRight;
|
||||
return 1;
|
||||
case ResizeTypeDown:
|
||||
ELOG("FrameEventHandler (resizing): ResizeTypeDown");
|
||||
curr_frame->set_cursor(CURSOR_S);
|
||||
ctype = CURSOR_S;
|
||||
bbbb = ResizeTypeDown;
|
||||
return 1;
|
||||
default:
|
||||
//curr_frame->set_cursor(CURSOR_DEFAULT);
|
||||
bbbb = ResizeTypeNone;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case FL_PUSH:
|
||||
ELOG("FrameEventHandler: FL_PUSH");
|
||||
|
||||
if(Fl::event_is_click())
|
||||
{
|
||||
curr_frame->borders_color(CLICKED);
|
||||
curr_frame->raise();
|
||||
}
|
||||
return 1;
|
||||
|
||||
case FL_DRAG:
|
||||
ELOG("FrameEventHandler: FL_DRAG");
|
||||
if(bbbb != ResizeTypeNone)
|
||||
{
|
||||
if(!curr_frame->resizing())
|
||||
{
|
||||
curr_frame->grab_cursor();
|
||||
curr_frame->resize_start();
|
||||
curr_frame->show_coordinates_window();
|
||||
}
|
||||
|
||||
//XGrabServer(fl_display);
|
||||
|
||||
curr_frame->set_cursor(ctype);
|
||||
curr_frame->resize_window(Fl::event_x_root(), Fl::event_y_root(), bbbb);
|
||||
curr_frame->update_coordinates_window();
|
||||
}
|
||||
return 1;
|
||||
|
||||
case FL_RELEASE:
|
||||
ELOG("FrameEventHandler: FL_RELEASE");
|
||||
if(curr_frame->resizing())
|
||||
{
|
||||
//XUngrabServer(fl_display);
|
||||
curr_frame->resize_end();
|
||||
curr_frame->ungrab_cursor();
|
||||
curr_frame->hide_coordinates_window();
|
||||
curr_frame->set_cursor(CURSOR_DEFAULT);
|
||||
}
|
||||
|
||||
//curr_frame->color(FL_GRAY);
|
||||
curr_frame->borders_color(FOCUSED);
|
||||
return 1;
|
||||
default:
|
||||
// let other events go to sizers
|
||||
return curr_frame->handle_parent(event);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int FrameEventHandler::handle_x(XEvent* event)
|
||||
{
|
||||
switch(event->type)
|
||||
{
|
||||
case MapRequest:
|
||||
return map_event(event->xmaprequest);
|
||||
case UnmapNotify:
|
||||
return unmap_event(event->xunmap);
|
||||
case ReparentNotify:
|
||||
return reparent_event(event->xreparent);
|
||||
case DestroyNotify:
|
||||
return destroy_event(event->xdestroywindow);
|
||||
/*case ClientMessage:
|
||||
return client_message(event->xclient);*/
|
||||
case LeaveNotify:
|
||||
case EnterNotify:
|
||||
return enter_leave_event(event->xcrossing);
|
||||
|
||||
/* FocusIn, as FocusOut is not used, but for
|
||||
* debugging is here. When we map a large number
|
||||
* of windows, X seems goes into (for me unknown)
|
||||
* infinite FocusIn/FocusOut loop, which blocks
|
||||
* everything. So, to keep us far away from pain,
|
||||
* leave FocusIn for someone else. Here should not
|
||||
* be used.
|
||||
*/
|
||||
case FocusIn:
|
||||
{
|
||||
ELOG("FrameEventHandler: FocusIn");
|
||||
switch(event->xfocus.mode)
|
||||
{
|
||||
case NotifyNormal:
|
||||
ELOG(" - NotifyNormal");
|
||||
break;
|
||||
case NotifyGrab:
|
||||
ELOG(" - NotifyGrab");
|
||||
break;
|
||||
case NotifyUngrab:
|
||||
ELOG(" - NotifyUngrab");
|
||||
break;
|
||||
}
|
||||
|
||||
if(event->xfocus.send_event)
|
||||
ELOG(" - got from SendEvent");
|
||||
|
||||
/* This will prevent menus, etc.
|
||||
* to steal focus from parent.
|
||||
*/
|
||||
//if(event->xfocus.mode == NotifyNormal)
|
||||
// curr_frame->focus();
|
||||
}
|
||||
return 1;
|
||||
|
||||
/* FocusOut really fuck up focusing so
|
||||
* it is not handled. Either xfocus.mode == NotifyNormal
|
||||
* does not helps when window emits menu, since menu
|
||||
* itself will yield FocusOut for parent and FocusIn
|
||||
* for itself. Unfortunately I don't know any toolkit
|
||||
* which export some kind MENU flag, where we can check.
|
||||
* So, let we shut it up, make ourself little bit happy
|
||||
* and take all burden of FocusOut to ourself (which made
|
||||
* use very very unhappy).
|
||||
*/
|
||||
case FocusOut:
|
||||
{
|
||||
ELOG("FrameEventHandler: FocusOut");
|
||||
switch(event->xfocus.mode)
|
||||
{
|
||||
case NotifyNormal:
|
||||
ELOG(" - NotifyNormal");
|
||||
break;
|
||||
case NotifyGrab:
|
||||
ELOG(" - NotifyGrab");
|
||||
break;
|
||||
case NotifyUngrab:
|
||||
ELOG(" - NotifyUngrab");
|
||||
break;
|
||||
}
|
||||
|
||||
if(event->xfocus.send_event)
|
||||
ELOG(" - got from SendEvent");
|
||||
//curr_frame->unfocus();
|
||||
}
|
||||
return 1;
|
||||
case PropertyNotify:
|
||||
return property_event(event->xproperty);
|
||||
case ConfigureRequest:
|
||||
return configure_event(event->xconfigurerequest);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
#ifdef _DEBUG
|
||||
const char* name = WindowManager::instance()->xevent_map[event->type];
|
||||
if(name)
|
||||
ELOG("Got unhandled %s in frame", name);
|
||||
else
|
||||
ELOG("Got unhandled event in frame (%i)", event->type);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FrameEventHandler::map_event(const XMapRequestEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::map_event(const XMapRequestEvent& e)");
|
||||
assert(e.window == curr_frame->window());
|
||||
|
||||
curr_frame->map();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FrameEventHandler::unmap_event(const XUnmapEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::unmap_event(const XUnmapEvent& e)");
|
||||
//assert(e.window == curr_frame->window());
|
||||
if(e.window != curr_frame->window())
|
||||
return 1;
|
||||
|
||||
ELOG("FrameEventHandler: UnmapNotify (%s)", FRAME_NAME(curr_frame->fdata));
|
||||
if(e.from_configure)
|
||||
return 1;
|
||||
|
||||
if(curr_frame->option(FrameOptIgnoreUnmap))
|
||||
{
|
||||
ELOG("Frame have FrameOptIgnoreUnmap, skiping this event");
|
||||
curr_frame->clear_option(FrameOptIgnoreUnmap);
|
||||
}
|
||||
else
|
||||
curr_frame->unmap();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FrameEventHandler::reparent_event(const XReparentEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::reparent_event(const XReparentEvent& e)");
|
||||
ELOG("FrameEventHandler: ReparentNotify (%s)", FRAME_NAME(curr_frame->fdata));
|
||||
|
||||
// echo
|
||||
if(e.parent == fl_xid(curr_frame))
|
||||
return 1;
|
||||
// app is trying to tear-off again ???
|
||||
if(e.parent == fl_xid(WindowManager::instance()))
|
||||
return 1;
|
||||
|
||||
if(e.override_redirect)
|
||||
{
|
||||
ELOG("override_redirect from reparent_event");
|
||||
}
|
||||
|
||||
EWARNING("Destroy in ReparentNotify!");
|
||||
curr_frame->destroy();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FrameEventHandler::destroy_event(const XDestroyWindowEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::destroy_event(const XDestroyWindowEvent& e)");
|
||||
|
||||
curr_frame->destroy();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FrameEventHandler::client_message(const XClientMessageEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::client_message(const XClientMessageEvent& e)");
|
||||
|
||||
if(!ValidateDrawable(e.window))
|
||||
return 1;
|
||||
|
||||
#ifdef _DEBUG
|
||||
Atom a = e.message_type;
|
||||
const char* name = WindowManager::instance()->atom_map[a];
|
||||
if(name)
|
||||
ELOG("FrameEventHandler: unhandled atom %s", name);
|
||||
else
|
||||
ELOG("FrameEventHandler: unhandled atom %x", a);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Handle property atoms. Here Netwm atoms are handled
|
||||
* last, giving them precedence and chance to overwrite
|
||||
* Icccm stuf (list XA_WM_NAME vs. _XA_NET_WM_NAME)
|
||||
*/
|
||||
int FrameEventHandler::property_event(const XPropertyEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::property_event(const XPropertyEvent& e)");
|
||||
|
||||
if(e.atom == XA_WM_NAME)
|
||||
ELOG("XA_WM_NAME");
|
||||
if(e.atom == XA_WM_ICON_NAME)
|
||||
ELOG("XA_WM_ICON_NAME");
|
||||
if(e.atom == XA_WM_HINTS)
|
||||
ELOG("XA_WM_HINTS");
|
||||
if(e.atom == XA_WM_NORMAL_HINTS)
|
||||
ELOG("XA_WM_NORMAL_HINTS");
|
||||
if(e.atom == XA_WM_SIZE_HINTS)
|
||||
ELOG("XA_WM_SIZE_HINTS");
|
||||
if(e.atom == XA_WM_TRANSIENT_FOR)
|
||||
ELOG("XA_WM_TRANSIENT_FOR");
|
||||
if(e.atom == _XA_WM_COLORMAP_WINDOWS)
|
||||
ELOG("_XA_WM_COLORMAP_WINDOWS");
|
||||
if(e.atom == _XA_WM_STATE)
|
||||
ELOG("_XA_WM_STATE");
|
||||
if(e.atom == _XA_WM_PROTOCOLS)
|
||||
ELOG("_XA_WM_PROTOCOLS");
|
||||
if(e.atom == _XA_NET_WM_WINDOW_TYPE)
|
||||
ELOG("_XA_NET_WM_WINDOW_TYPE");
|
||||
if(e.atom == _XA_NET_WM_STRUT)
|
||||
{
|
||||
ELOG("_XA_NET_WM_STRUT");
|
||||
int dummy;
|
||||
WindowManager::instance()->hints()->netwm_strut(curr_frame->fdata->window,
|
||||
&dummy, &dummy, &dummy, &dummy);
|
||||
}
|
||||
if(e.atom == _XA_NET_WM_NAME)
|
||||
ELOG("_XA_NET_WM_NAME");
|
||||
if(e.atom == _XA_NET_WM_ICON)
|
||||
ELOG("_XA_NET_WM_ICON");
|
||||
if(e.atom == _XA_KWM_WIN_ICON)
|
||||
ELOG("_XA_KWM_WIN_ICON");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Handle EnterNotify and LeaveNotify events.
|
||||
* Here is used only LeaveNotify to change cursor, since it will be
|
||||
* trigered only on window borders (exact what is needed). On other
|
||||
* hand, entering frame's child (or plain window) is handled by
|
||||
* window itself, with ability to change cursor as like.
|
||||
* Note, this event could not be simulated with FL_LEAVE, since
|
||||
* it will be trigered only when mouse if off from whole window
|
||||
* (including childs).
|
||||
*
|
||||
* Also, checkings of frame resizings are must, since mouse moving is
|
||||
* usually faster than window resizing, so we will get flickering in
|
||||
* cursors changes if not checked.
|
||||
*
|
||||
* TODO: better will be cursor is grabbed !
|
||||
*/
|
||||
int FrameEventHandler::enter_leave_event(const XCrossingEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::enter_event(const XEnterWindowEvent& e)");
|
||||
if(curr_frame->state(FrameStateUnmapped))
|
||||
return 1;
|
||||
|
||||
if(e.type == LeaveNotify && !curr_frame->resizing())
|
||||
curr_frame->set_cursor(CURSOR_DEFAULT);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This message we can get for windows we know about and we don't know
|
||||
* about (since all root messages are redirected to us). So we first check
|
||||
* is window is managed by us, and apply changes to it via our functions.
|
||||
* Otherwise, we configure window directly.
|
||||
*
|
||||
* Note: in fltk's fluid(1.1.6), setting x coords will send us pretty
|
||||
* amount of junk (change x and y in the same time !!!). This is probably
|
||||
* bug in fluid.
|
||||
*/
|
||||
int FrameEventHandler::configure_event(const XConfigureRequestEvent& e)
|
||||
{
|
||||
TRACE_FUNCTION("int FrameEventHandler::configure_event(const XConfigureRequestEvent& e)");
|
||||
|
||||
if(curr_frame->state(FrameStateUnmapped))
|
||||
return 1;
|
||||
|
||||
if(curr_frame->window() == e.window)
|
||||
{
|
||||
ELOG("ConfigureRequest from frame");
|
||||
if(!ValidateDrawable(curr_frame->window()))
|
||||
return 1;
|
||||
|
||||
int x_pos = curr_frame->fdata->plain.x;
|
||||
int y_pos = curr_frame->fdata->plain.y;
|
||||
int w_sz = curr_frame->fdata->plain.w;
|
||||
int h_sz = curr_frame->fdata->plain.h;
|
||||
|
||||
if(e.value_mask & CWX)
|
||||
x_pos = e.x;
|
||||
if(e.value_mask & CWY)
|
||||
y_pos = e.y;
|
||||
if(e.value_mask & CWWidth)
|
||||
w_sz = e.width;
|
||||
if(e.value_mask & CWHeight)
|
||||
h_sz = e.height;
|
||||
|
||||
if(e.value_mask & CWStackMode)
|
||||
{
|
||||
if(e.detail == Above)
|
||||
curr_frame->raise();
|
||||
if(e.detail == Below)
|
||||
curr_frame->lower();
|
||||
}
|
||||
|
||||
curr_frame->set_size(x_pos, y_pos, w_sz, h_sz, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ELOG("ConfigureRequest from unhandled window");
|
||||
|
||||
if(ValidateDrawable(e.window))
|
||||
{
|
||||
XWindowChanges wc;
|
||||
wc.x = e.x;
|
||||
wc.y = e.y;
|
||||
wc.width = e.width;
|
||||
wc.height = e.height;
|
||||
wc.stack_mode = e.detail;
|
||||
XConfigureWindow(fl_display, e.window, e.value_mask, &wc);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
Reference in New Issue
Block a user