mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Copying wm from old ede
This commit is contained in:
parent
f8c3e1ff7c
commit
7513426131
143
edewm/Cursor.cpp
Normal file
143
edewm/Cursor.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
#include "Frame.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#include <efltk/Fl.h>
|
||||
#include <efltk/Fl_Window.h>
|
||||
#include <efltk/x.h>
|
||||
|
||||
// I like the MSWindows resize cursors, so I duplicate them here:
|
||||
|
||||
#define CURSORSIZE 16
|
||||
#define HOTXY 8
|
||||
static struct TableEntry {
|
||||
uchar bits[CURSORSIZE*CURSORSIZE/8];
|
||||
uchar mask[CURSORSIZE*CURSORSIZE/8];
|
||||
Cursor cursor;
|
||||
} table[] = {
|
||||
{{ // FL_CURSOR_NS
|
||||
0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00},
|
||||
{
|
||||
0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
|
||||
0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
|
||||
0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}},
|
||||
{{ // FL_CURSOR_EW
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
|
||||
0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
|
||||
0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{ // FL_CURSOR_NWSE
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
|
||||
0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
|
||||
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
|
||||
0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
|
||||
0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{ // FL_CURSOR_NESW
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e,
|
||||
0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00,
|
||||
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f,
|
||||
0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00,
|
||||
0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0}, {0}} // FL_CURSOR_NONE & unknown
|
||||
};
|
||||
|
||||
static int deleteit = 0;
|
||||
static Cursor cursor;
|
||||
void set_frame_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg, Window wid)
|
||||
{
|
||||
if(deleteit) XFreeCursor(fl_display, cursor);
|
||||
deleteit=0;
|
||||
|
||||
if (!c) {
|
||||
cursor = None;
|
||||
} else {
|
||||
if (c >= FL_CURSOR_NS) {
|
||||
TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS);
|
||||
if (!(q->cursor)) {
|
||||
XColor dummy;
|
||||
Pixmap p = XCreateBitmapFromData(fl_display,
|
||||
RootWindow(fl_display, fl_screen), (const char*)(q->bits),
|
||||
CURSORSIZE, CURSORSIZE);
|
||||
Pixmap m = XCreateBitmapFromData(fl_display,
|
||||
RootWindow(fl_display, fl_screen), (const char*)(q->mask),
|
||||
CURSORSIZE, CURSORSIZE);
|
||||
q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy,
|
||||
HOTXY, HOTXY);
|
||||
XFreePixmap(fl_display, m);
|
||||
XFreePixmap(fl_display, p);
|
||||
}
|
||||
cursor = q->cursor;
|
||||
} else {
|
||||
cursor = XCreateFontCursor(fl_display, (c-1)*2);
|
||||
deleteit = 1;
|
||||
}
|
||||
XColor fgc;
|
||||
fg = fl_get_color(fg);
|
||||
fgc.red = (fg>>16)&0xFF00;
|
||||
fgc.green = (fg>>8)&0xFF00;
|
||||
fgc.blue = fg & 0xFF00;
|
||||
XColor bgc;
|
||||
bg = fl_get_color(bg);
|
||||
bgc.red = (bg>>16)&0xFF00;
|
||||
bgc.green = (bg>>8)&0xFF00;
|
||||
bgc.blue = bg & 0xFF00;
|
||||
XRecolorCursor(fl_display, cursor, &fgc, &bgc);
|
||||
}
|
||||
XDefineCursor(fl_display, wid, cursor);
|
||||
}
|
||||
|
||||
static bool grab_ = false;
|
||||
void grab_cursor(bool grab)
|
||||
{
|
||||
if (grab_) {
|
||||
grab_ = false;
|
||||
Fl::event_is_click(0); // avoid double click
|
||||
XAllowEvents(fl_display, Fl::event()==FL_PUSH ? ReplayPointer : AsyncPointer, CurrentTime);
|
||||
XUngrabPointer(fl_display, fl_event_time); // Qt did not do this...
|
||||
XFlush(fl_display); // make sure we are out of danger before continuing...
|
||||
// because we "pushed back" the FL_PUSH, make it think no buttons are down:
|
||||
Fl::e_state &= 0xffffff;
|
||||
Fl::e_keysym = 0;
|
||||
}
|
||||
|
||||
// start the new grab:
|
||||
// Both X and Win32 have the annoying requirement that a visible window
|
||||
// be used as a target for the events, and it cannot disappear while the
|
||||
// grab is running. I just grab efltk's first window:
|
||||
if(grab && Frame::activeFrame()) {
|
||||
Window window = fl_xid(Frame::activeFrame());
|
||||
if(window &&
|
||||
XGrabPointer(fl_display,
|
||||
window,
|
||||
true, // owner_events
|
||||
ButtonPressMask|ButtonReleaseMask|
|
||||
ButtonMotionMask|PointerMotionMask,
|
||||
GrabModeSync, // pointer_mode
|
||||
GrabModeAsync, // keyboard_mode
|
||||
None, // confine_to
|
||||
cursor, // cursor
|
||||
fl_event_time) == GrabSuccess)
|
||||
{
|
||||
grab_ = true;
|
||||
XAllowEvents(fl_display, AsyncPointer, CurrentTime);
|
||||
} else {
|
||||
//printf("XGrabPointer failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool grab() {
|
||||
return grab_;
|
||||
}
|
||||
|
||||
|
296
edewm/Desktop.cpp
Normal file
296
edewm/Desktop.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "Winhints.h"
|
||||
#include "Frame.h"
|
||||
#include "Windowmanager.h"
|
||||
#include "Desktop.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Desktop_List desktops;
|
||||
|
||||
int Desktop::desktop_count_ = 0;
|
||||
Desktop* Desktop::current_ = 0;
|
||||
|
||||
Desktop *Desktop::desktop(int num)
|
||||
{
|
||||
if(num>=(int)desktops.size()) return desktops.item(desktops.size()-1);
|
||||
if(num<1) return desktops.item(0);
|
||||
|
||||
for(uint n=0; n<desktops.size(); n++) {
|
||||
Desktop *d=desktops[n];
|
||||
if(d->number()==num) return d;
|
||||
}
|
||||
return desktops.item(0);
|
||||
}
|
||||
|
||||
Desktop *Desktop::next()
|
||||
{
|
||||
uint num = current()->number();
|
||||
num++;
|
||||
if(num > desktops.count())
|
||||
current(0);
|
||||
else
|
||||
current(num);
|
||||
return current();
|
||||
}
|
||||
|
||||
Desktop *Desktop::prev()
|
||||
{
|
||||
int num = current()->number();
|
||||
num--;
|
||||
if(num < 1)
|
||||
current(desktops.count());
|
||||
else
|
||||
current(num);
|
||||
return current();
|
||||
}
|
||||
|
||||
Desktop::Desktop(const char *name)
|
||||
{
|
||||
desktops.append(this);
|
||||
number_ = desktops.count();
|
||||
|
||||
DBG("::Desktop %d", number_);
|
||||
|
||||
if(name)
|
||||
name_ = strdup(name);
|
||||
else
|
||||
name_ = 0;
|
||||
}
|
||||
|
||||
Desktop::~Desktop()
|
||||
{
|
||||
desktops.remove(this);
|
||||
if(current_==this) {
|
||||
current(desktop(number()+1));
|
||||
}
|
||||
|
||||
// put any clients onto another desktop:
|
||||
for(uint n=0; n<map_order.size(); n++)
|
||||
if(map_order[n]->desktop()==this)
|
||||
map_order[n]->desktop(current_);
|
||||
|
||||
if(name_) delete []name_;
|
||||
}
|
||||
|
||||
void Desktop::name(const char *name)
|
||||
{
|
||||
if(name_) delete []name_;
|
||||
if(name) name_ = strdup(name);
|
||||
}
|
||||
|
||||
extern Frame *menu_frame; //Frame where titlebar menu is popped up. Set only when changing window desktop.
|
||||
void Desktop::current(Desktop *cur)
|
||||
{
|
||||
if(cur == current_) return;
|
||||
|
||||
current_ = cur;
|
||||
|
||||
Frame *f = 0, *top = 0;
|
||||
for(uint n=0; n<stack_order.size(); n++) {
|
||||
f = stack_order[n];
|
||||
if(!f->desktop() && f->state()!=UNMAPPED) {
|
||||
if(f->state()==OTHER_DESKTOP) f->state(NORMAL);
|
||||
if(!f->frame_flag(SKIP_FOCUS) && !f->frame_flag(SKIP_LIST)) top=f;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Keep this window in 'NORMAL' state.
|
||||
if(f==menu_frame && f->state()==NORMAL) {
|
||||
top=f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(f->state()!=UNMAPPED) {
|
||||
if(f->desktop()==cur) {
|
||||
if(f->state()==OTHER_DESKTOP) {
|
||||
f->state(NORMAL);
|
||||
}
|
||||
top=f;
|
||||
|
||||
} else {
|
||||
|
||||
if(f->state()==NORMAL) {
|
||||
f->state(OTHER_DESKTOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cur!=0) {
|
||||
setProperty(fl_xid(root), _XA_NET_CURRENT_DESKTOP, XA_CARDINAL, cur->number()-1);
|
||||
if(top) {
|
||||
top->activate();
|
||||
top->raise();
|
||||
}
|
||||
DBG("Went to desktop: %d", cur->number());
|
||||
}
|
||||
}
|
||||
|
||||
Desktop* Desktop::add(const char *name)
|
||||
{
|
||||
Desktop *d = new Desktop(name);
|
||||
if(!name) {
|
||||
char buf[32]; sprintf(buf, _("Workspace %d"), d->number());
|
||||
d->name(buf);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Updates viewport info, since we dont support LARGE desktops
|
||||
// According to NET-WM speac these MUST be set to (0,0)
|
||||
void Desktop::update_desktop_viewport()
|
||||
{
|
||||
CARD32 val[2] = { 0, 0 };
|
||||
XChangeProperty(fl_display, root_win, _XA_NET_DESKTOP_VIEWPORT, XA_CARDINAL,
|
||||
32, PropModeReplace, (unsigned char *)&val, 2);
|
||||
}
|
||||
|
||||
void Desktop::update_desktop_geometry()
|
||||
{
|
||||
CARD32 val[2] = { Fl::w(), Fl::h() };
|
||||
XChangeProperty(fl_display, root_win, _XA_NET_DESKTOP_GEOMETRY, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char *)&val, 2);
|
||||
|
||||
}
|
||||
|
||||
void Desktop::update_desktop_workarea()
|
||||
{
|
||||
CARD32 val[4];
|
||||
val[0] = root->x();
|
||||
val[1] = root->y();
|
||||
val[2] = root->w();
|
||||
val[3] = root->h();
|
||||
|
||||
XChangeProperty(fl_display, root_win, _XA_NET_WORKAREA, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char *)&val, 4);
|
||||
}
|
||||
|
||||
void Desktop::update_desktop_names(bool send)
|
||||
{
|
||||
char *workspaces[16] = { 0 };
|
||||
int cnt=0;
|
||||
for(uint n=0; n<desktops.size(); n++) {
|
||||
Desktop *d=desktops[n];
|
||||
if(!d->name()) {
|
||||
char tmp[64]; snprintf(tmp, sizeof(tmp)-1, _("Workspace %d"), cnt+1);
|
||||
workspaces[cnt] = strdup(tmp);
|
||||
} else {
|
||||
workspaces[cnt] = strdup(d->name());
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if(send) {
|
||||
XTextProperty names;
|
||||
if(XStringListToTextProperty((char **)workspaces, cnt, &names)) {
|
||||
XSetTextProperty(fl_display, fl_xid(root), &names, _XA_NET_DESKTOP_NAMES);
|
||||
XFree(names.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updates both NET desktop count atoms
|
||||
void Desktop::update_desktop_count(uint cnt, bool send)
|
||||
{
|
||||
if(cnt<0) cnt=0;
|
||||
if(cnt>8) cnt=8;
|
||||
|
||||
Desktop::desktop_count_ = cnt;
|
||||
if(send) {
|
||||
setProperty(fl_xid(root), _XA_NET_NUM_DESKTOPS, XA_CARDINAL, Desktop::desktop_count_);
|
||||
|
||||
update_desktop_viewport();
|
||||
update_desktop_workarea();
|
||||
update_desktop_geometry();
|
||||
}
|
||||
|
||||
if(desktops.count()<cnt) {
|
||||
int add = cnt-desktops.count();
|
||||
for(int a=0; a<add; a++)
|
||||
Desktop::add();
|
||||
DBG("Increased desktops to %d", desktops.count());
|
||||
} else if(desktops.count()>cnt) {
|
||||
int del = desktops.count()-cnt;
|
||||
for(int a=0; a<del; a++) {
|
||||
Desktop *d = desktops.item(desktops.size()-1);
|
||||
delete d;
|
||||
}
|
||||
DBG("Decreased desktops to %d", desktops.count());
|
||||
}
|
||||
}
|
||||
|
||||
void Desktop::set_names()
|
||||
{
|
||||
int length=0;
|
||||
char *buffer=0;
|
||||
|
||||
XTextProperty names;
|
||||
// First try to get NET desktop names
|
||||
XGetTextProperty(fl_display, RootWindow(fl_display, fl_screen), &names, _XA_NET_DESKTOP_NAMES);
|
||||
buffer = (char *)names.value;
|
||||
length = names.nitems;
|
||||
|
||||
if(buffer) {
|
||||
char* c = buffer;
|
||||
for (int i = 1; c < buffer+length; i++) {
|
||||
char* d = c;
|
||||
while(*d) d++;
|
||||
Desktop::desktop(i)->name(c);
|
||||
c = d+1;
|
||||
}
|
||||
XFree(names.value);
|
||||
|
||||
} else {
|
||||
// No desktop names in XServer already, read from ede config file
|
||||
Fl_Config cfg(fl_find_config_file("ede.conf", 0));
|
||||
cfg.set_section("Workspaces");
|
||||
char tmp[128], name[128];
|
||||
for(uint n=1; n<=8; n++) {
|
||||
snprintf(tmp, sizeof(tmp)-1, "Workspace%d", n);
|
||||
if(!cfg.read(tmp, name, 0, sizeof(name))) {
|
||||
if(n<=desktops.count()) {
|
||||
Desktop::desktop(n)->name(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called at startup, read the list of desktops from the root
|
||||
// window properties, or on failure make some default desktops.
|
||||
void init_desktops()
|
||||
{
|
||||
int current_num=0, p=0;
|
||||
|
||||
p = getIntProperty(fl_xid(root), _XA_NET_NUM_DESKTOPS, XA_CARDINAL, -1);
|
||||
if(p<0) {
|
||||
// No desktop count in XServer already, read from ede config file
|
||||
Fl_Config cfg(fl_find_config_file("ede.conf", 0));
|
||||
cfg.get("Workspaces", "Count", p, 4);
|
||||
}
|
||||
|
||||
DBG("Total Desks: %d", p);
|
||||
|
||||
Desktop::update_desktop_count(p);
|
||||
Desktop::set_names();
|
||||
Desktop::update_desktop_names(true);
|
||||
|
||||
// Try to get current NET desktop
|
||||
p = getIntProperty(fl_xid(root), _XA_NET_CURRENT_DESKTOP, XA_CARDINAL, -1);
|
||||
// If not valid number, try GNOME
|
||||
if(p >= 0 && p < Desktop::desktop_count()+1)
|
||||
current_num = p+1; // Got valid
|
||||
else
|
||||
current_num = 1; // Not valid, use 1
|
||||
|
||||
DBG("Current desktop: %d", current_num);
|
||||
Desktop::current(Desktop::desktop(current_num));
|
||||
|
||||
DBG("Desktops inited!");
|
||||
}
|
||||
|
69
edewm/Desktop.h
Normal file
69
edewm/Desktop.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef _DESKTOP_H_
|
||||
#define _DESKTOP_H_
|
||||
|
||||
#include <efltk/Fl_PtrList.h>
|
||||
|
||||
class Desktop {
|
||||
public:
|
||||
Desktop(const char *name);
|
||||
~Desktop();
|
||||
|
||||
const char* name() const { return name_; }
|
||||
void name(const char *name);
|
||||
int number() const { return number_; }
|
||||
|
||||
static Desktop *desktop(int num);
|
||||
|
||||
static Desktop *next();
|
||||
static Desktop *prev();
|
||||
|
||||
static Desktop *current() { return current_; }
|
||||
static int current_num() { return current_ ? current_->number() : -1; }
|
||||
|
||||
static Desktop* add(const char *name=0);
|
||||
|
||||
static void current(Desktop *cur);
|
||||
static void current(int cur) { current(desktop(cur)); }
|
||||
|
||||
static int desktop_count() { return desktop_count_; }
|
||||
|
||||
static void update_desktop_viewport();
|
||||
static void update_desktop_workarea();
|
||||
static void update_desktop_geometry();
|
||||
|
||||
static void update_desktop_count(uint cnt, bool send=true);
|
||||
static void update_desktop_names(bool send=true);
|
||||
|
||||
static void set_names();
|
||||
|
||||
int junk; // for temporary storage by menu builder
|
||||
|
||||
private:
|
||||
static Desktop* current_;
|
||||
static int desktop_count_;
|
||||
|
||||
const char* name_;
|
||||
int number_;
|
||||
};
|
||||
|
||||
class Desktop_List : public Fl_Ptr_List {
|
||||
public:
|
||||
Desktop_List() : Fl_Ptr_List() { }
|
||||
|
||||
void append(Desktop *item) { Fl_Ptr_List::append((void *)item); }
|
||||
void prepend(Desktop *item) { Fl_Ptr_List::prepend((void *)item); }
|
||||
void insert(uint pos, Desktop *item) { Fl_Ptr_List::insert(pos, (void *)item); }
|
||||
void replace(uint pos, Desktop *item) { Fl_Ptr_List::replace(pos, (void *)item); }
|
||||
void remove(uint pos) { Fl_Ptr_List::remove(pos); }
|
||||
bool remove(Desktop *item) { return Fl_Ptr_List::remove((void *)item); }
|
||||
int index_of(const Desktop *w) const { return Fl_Ptr_List::index_of((void*)w); }
|
||||
Desktop *item(uint index) const { return (Desktop*)Fl_Ptr_List::item(index); }
|
||||
|
||||
Desktop **data() { return (Desktop**)items; }
|
||||
|
||||
Desktop *operator [](uint ind) const { return (Desktop *)items[ind]; }
|
||||
};
|
||||
|
||||
extern Desktop_List desktops;
|
||||
|
||||
#endif
|
375
edewm/Events.cpp
Normal file
375
edewm/Events.cpp
Normal file
@ -0,0 +1,375 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Frame.h"
|
||||
#include "Desktop.h"
|
||||
#include "Netwm.h"
|
||||
#include "Windowmanager.h"
|
||||
#include "Icon.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "Winhints.h"
|
||||
|
||||
bool Frame::configure_event(const XConfigureRequestEvent *e)
|
||||
{
|
||||
DBG("configure_event 0x%lx", e->window);
|
||||
// Always update flags and border...
|
||||
get_funcs_from_type();
|
||||
updateBorder();
|
||||
|
||||
unsigned long mask = e->value_mask;
|
||||
//if (mask & CWBorderWidth) app_border_width = e->border_width;
|
||||
|
||||
// Try to detect if the application is really trying to move the
|
||||
// window, or is simply echoing it's postion, possibly with some
|
||||
// variation (such as echoing the parent window position), and
|
||||
// dont' move it in that case:
|
||||
int X = (mask & CWX && e->x != x()) ? e->x-offset_x : x();
|
||||
int Y = (mask & CWY && e->y != y()) ? e->y-offset_y : y();
|
||||
|
||||
int W = (mask & CWWidth) ? e->width+offset_w : w();
|
||||
int H = (mask & CWHeight) ? e->height+offset_h : h();
|
||||
|
||||
// Fix Rick Sayre's program that resizes it's windows bigger than the maximum size:
|
||||
// Just turn off sizehints
|
||||
if(W > size_hints->max_width + offset_w) size_hints->max_width = 0;
|
||||
if(H > size_hints->max_height + offset_h) size_hints->max_height = 0;
|
||||
|
||||
set_size(X, Y, W, H);
|
||||
|
||||
if (e->value_mask & CWStackMode && e->detail == Above && state()==NORMAL)
|
||||
raise();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::map_event(const XMapRequestEvent *e)
|
||||
{
|
||||
DBG("map_event 0x%lx", e->window);
|
||||
|
||||
if(state()!=NORMAL) state(NORMAL);
|
||||
activate();
|
||||
raise();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::unmap_event(const XUnmapEvent *e)
|
||||
{
|
||||
DBG("unmap_event 0x%lx", e->window);
|
||||
|
||||
if(state()==OTHER_DESKTOP) return true;
|
||||
if(state()==ICONIC) return true;
|
||||
|
||||
if(e->from_configure)
|
||||
{
|
||||
DBG("Unmap notify from configure\n");
|
||||
state(UNMAPPED);
|
||||
} else if(state_flags_&IGNORE_UNMAP)
|
||||
clear_state_flag(IGNORE_UNMAP);
|
||||
else
|
||||
state(UNMAPPED);
|
||||
|
||||
WindowManager::update_client_list();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::destroy_event(const XDestroyWindowEvent *e)
|
||||
{
|
||||
DBG("destroy_event 0x%lx", e->window);
|
||||
destroy_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::reparent_event(const XReparentEvent *e)
|
||||
{
|
||||
DBG("reparent_event 0x%lx", e->window);
|
||||
|
||||
if(e->parent==fl_xid(this)) return true; // echo
|
||||
if(e->parent==fl_xid(root)) return true; // app is trying to tear-off again?
|
||||
|
||||
DBG("Destroy in reparent_event");
|
||||
destroy_frame(); // guess they are trying to paste tear-off thing back?
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <efltk/fl_ask.h>
|
||||
bool Frame::clientmsg_event(const XClientMessageEvent *e)
|
||||
{
|
||||
DBG("clientmsg_event 0x%lx", e->window);
|
||||
|
||||
if(e->message_type == _XA_WM_CHANGE_STATE && e->format == 32)
|
||||
{
|
||||
DBG("WIN change state");
|
||||
if (e->data.l[0] == NormalState) raise();
|
||||
else if (e->data.l[0] == IconicState) iconize();
|
||||
return true;
|
||||
|
||||
}
|
||||
else if(e->message_type == _XA_NET_WM_STATE)
|
||||
{
|
||||
/* int action = e->data.l[0]; */
|
||||
Atom atom1 = e->data.l[1];
|
||||
Atom atom2 = e->data.l[2];
|
||||
|
||||
// We accepts only HORZ - VERT combination (sent by taskbar).
|
||||
// Horizontal or vertical maximization only, is not supported for now.
|
||||
if((atom1 == _XA_NET_WM_STATE_MAXIMIZED_HORZ || atom1 == _XA_NET_WM_STATE_MAXIMIZED_VERT) &&
|
||||
atom2 == _XA_NET_WM_STATE_MAXIMIZED_HORZ || atom2 == _XA_NET_WM_STATE_MAXIMIZED_VERT)
|
||||
{
|
||||
maximize();
|
||||
return true;
|
||||
}
|
||||
|
||||
DBG("NET state");
|
||||
}
|
||||
else if(e->message_type == _XA_NET_ACTIVE_WINDOW)
|
||||
{
|
||||
|
||||
DBG("Net active window: %ld", e->window);
|
||||
raise();
|
||||
activate();
|
||||
return true;
|
||||
|
||||
}
|
||||
else if(e->message_type == _XA_NET_CLOSE_WINDOW)
|
||||
{
|
||||
|
||||
DBG("Net close window: %ld", e->window);
|
||||
close();
|
||||
return true;
|
||||
|
||||
}
|
||||
else if(e->message_type == _XA_NET_WM_DESKTOP)
|
||||
{
|
||||
|
||||
DBG("Net wm desktop: %ld", e->window);
|
||||
long d = e->data.l[0];
|
||||
if(d<0) d=1;
|
||||
else if(d>8) d=8;
|
||||
else if((unsigned)d == 0xFFFFFFFE || (unsigned)d == 0xFFFFFFFF) d=-2;
|
||||
else d++;
|
||||
|
||||
if(d>0) desktop(Desktop::desktop(d));
|
||||
else desktop(0);
|
||||
return true;
|
||||
|
||||
}
|
||||
else if(e->message_type ==_XA_EDE_WM_ACTION)
|
||||
{
|
||||
Atom atom = e->data.l[0];
|
||||
if(atom == _XA_EDE_WM_RESTORE_SIZE)
|
||||
{
|
||||
restore();
|
||||
return true;
|
||||
}
|
||||
if(atom == _XA_EDE_WM_LOGOUT)
|
||||
{
|
||||
root->shutdown();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fl::warning("flwm: unexpected XClientMessageEvent, type 0x%lx, "
|
||||
// "window 0x%lx\n", e->message_type, e->window);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::colormap_event(const XColormapEvent *e)
|
||||
{
|
||||
DBG("colormap_event 0x%lx", e->window);
|
||||
|
||||
// this field is called "new" in the old C++-unaware Xlib
|
||||
if(e->c_new)
|
||||
{
|
||||
colormap = e->colormap;
|
||||
if(active())
|
||||
installColormap();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::property_event(const XPropertyEvent *e)
|
||||
{
|
||||
DBG("property_event 0x%lx", e->window);
|
||||
|
||||
Atom a = e->atom;
|
||||
|
||||
switch(a)
|
||||
{
|
||||
|
||||
case XA_WM_NAME:
|
||||
getLabel((e->state==PropertyDelete), XA_WM_NAME);
|
||||
break;
|
||||
|
||||
case XA_WM_ICON_NAME:
|
||||
break;
|
||||
|
||||
case XA_WM_HINTS:
|
||||
{
|
||||
get_wm_hints();
|
||||
Icon *old_i = icon_;
|
||||
icon_ = new Icon(wm_hints);
|
||||
if(old_i) delete old_i;
|
||||
old_i=0;
|
||||
title->redraw();
|
||||
redraw();
|
||||
}
|
||||
break;
|
||||
|
||||
case XA_WM_NORMAL_HINTS:
|
||||
case XA_WM_SIZE_HINTS:
|
||||
ICCCM::size_hints(this);
|
||||
break;
|
||||
|
||||
case XA_WM_TRANSIENT_FOR:
|
||||
XGetTransientForHint(fl_display, window_, &transient_for_xid);
|
||||
fix_transient_for();
|
||||
break;
|
||||
|
||||
default:
|
||||
if(a==_XA_WM_COLORMAP_WINDOWS)
|
||||
{
|
||||
|
||||
getColormaps();
|
||||
if (active()) installColormap();
|
||||
|
||||
}
|
||||
else if(a==_XA_WM_STATE)
|
||||
{
|
||||
|
||||
// it's not clear if I really need to look at this. Need to make
|
||||
// sure it is not seeing the state echoed by the application by
|
||||
// checking for it being different...
|
||||
switch (getIntProperty(_XA_WM_STATE, _XA_WM_STATE, state()))
|
||||
{
|
||||
case IconicState:
|
||||
if (state() == NORMAL || state() == OTHER_DESKTOP)
|
||||
{
|
||||
iconize();
|
||||
}
|
||||
break;
|
||||
case NormalState:
|
||||
if (state() != NORMAL && state() != OTHER_DESKTOP)
|
||||
{
|
||||
raise();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if(a==_XATOM_MWM_HINTS)
|
||||
{
|
||||
|
||||
// some SGI Motif programs change this after mapping the window!!!
|
||||
MWM::get_hints(this);
|
||||
if(MWM::update_hints(this)) // returns true if any flags changed
|
||||
{
|
||||
fix_transient_for();
|
||||
updateBorder();
|
||||
}
|
||||
|
||||
}
|
||||
else if(a==_XA_WM_PROTOCOLS)
|
||||
{
|
||||
|
||||
get_protocols();
|
||||
//getMotifHints(); // get Motif hints since they may do something with QUIT
|
||||
|
||||
}
|
||||
else if(a==_XA_NET_WM_WINDOW_TYPE)
|
||||
{
|
||||
|
||||
DBG("New NET WM window type!");
|
||||
|
||||
if(NETWM::get_window_type(this))
|
||||
{
|
||||
// This call overwrites MWM hints!
|
||||
get_funcs_from_type();
|
||||
} // && wintype==TYPE_NORMAL && decor_flag(BORDER)) {
|
||||
else if(transient_for_xid)
|
||||
{
|
||||
//title->h(15); title->label(0);
|
||||
if(decor_flag(BORDER) || decor_flag(THIN_BORDER))
|
||||
{
|
||||
clear_decor_flag(BORDER);
|
||||
set_decor_flag(THIN_BORDER);
|
||||
wintype = TYPE_DIALOG;
|
||||
get_funcs_from_type();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(a==_XA_NET_WM_STRUT)
|
||||
{
|
||||
|
||||
DBG("New NET WM STRUT");
|
||||
NETWM::get_strut(this);
|
||||
root->update_workarea(true);
|
||||
|
||||
}
|
||||
else if(a== _XA_NET_WM_NAME)
|
||||
{
|
||||
|
||||
DBG("New NET WM NAME!");
|
||||
getLabel((e->state==PropertyDelete), _XA_NET_WM_NAME);
|
||||
|
||||
}
|
||||
else if(a== _XA_NET_WM_ICON)
|
||||
{
|
||||
|
||||
DBG("New NET icon!");
|
||||
|
||||
}
|
||||
else if(a== _XA_KWM_WIN_ICON)
|
||||
{
|
||||
|
||||
DBG("New KWM icon!");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
DBG("Unhandled atom %lx\n", a);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::visibility_event(const XVisibilityEvent *e)
|
||||
{
|
||||
DBG("visibility_event 0x%lx", e->window);
|
||||
|
||||
// POSSIBLE SPEED UP!
|
||||
// if e->state==FullyObscured we dont need to
|
||||
// map/draw window, when we change desktop!
|
||||
|
||||
/*if(e->state == VisibilityUnobscured)
|
||||
DBG("Fully visible");
|
||||
else
|
||||
DBG("Partial visible");
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SHAPE
|
||||
bool Frame::shape_event(const XShapeEvent *e)
|
||||
{
|
||||
DBG("shape event 0x%lx", e->window);
|
||||
XShapeSelectInput(fl_display, window_, ShapeNotifyMask);
|
||||
if(get_shape())
|
||||
{
|
||||
clear_decor_flag(BORDER|THIN_BORDER);
|
||||
XShapeCombineShape(fl_display, fl_xid(this), ShapeBounding,
|
||||
0, 0, window_,
|
||||
ShapeBounding, ShapeSet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
1674
edewm/Frame.cpp
Normal file
1674
edewm/Frame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
313
edewm/Frame.h
Normal file
313
edewm/Frame.h
Normal file
@ -0,0 +1,313 @@
|
||||
// Frame.H
|
||||
|
||||
// Each X window being managed by fltk has one of these
|
||||
|
||||
#ifndef Frame_H
|
||||
#define Frame_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Mwm.h"
|
||||
#include "Icccm.h"
|
||||
|
||||
#include <efltk/Fl.h>
|
||||
#include <efltk/Fl_Window.h>
|
||||
#include <efltk/Fl_Button.h>
|
||||
#include <efltk/Fl_Bitmap.h>
|
||||
#include <efltk/x.h>
|
||||
|
||||
#ifdef SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
|
||||
#include <efltk/Fl_Image.h>
|
||||
|
||||
// The state is an enumeration of reasons why the window may be invisible.
|
||||
// Only if it is NORMAL is the window visible.
|
||||
enum {
|
||||
UNMAPPED = 0, // unmap command from app (X calls this WithdrawnState)
|
||||
NORMAL = 1, // window is visible
|
||||
SHADED = 2, // acts like NORMAL
|
||||
ICONIC = 3, // hidden/iconized
|
||||
OTHER_DESKTOP = 4 // normal but on another desktop
|
||||
};
|
||||
|
||||
// values for frame flags:
|
||||
// The flags are constant and are turned on by information learned
|
||||
// from the Gnome, NETWM, and/or Motif window manager hints. edewm will
|
||||
// ignore attempts to change these hints after the window is mapped.
|
||||
enum {
|
||||
NO_FOCUS = 0x00000001, // does not take focus
|
||||
CLICK_TO_FOCUS = 0x00000002, // must click on window to give it focus
|
||||
KEEP_ASPECT = 0x00000004, // aspect ratio from sizeHints
|
||||
|
||||
MODAL = 0x00000008, // grabs focus from transient_for window
|
||||
|
||||
TAKE_FOCUS_PRT = 0x00000010, // send junk when giving window focus
|
||||
DELETE_WIN_PRT = 0x00000020, // close box sends a message
|
||||
|
||||
MAX_VERT = 0x00000100,
|
||||
MAX_HORZ = 0x00000200,
|
||||
STICKY = 0x00000400, // Everyone knows sticky
|
||||
OWNER_HIDDEN = 0x00000800, // Owner of transient is hidden
|
||||
FIXED_POSITION = 0x00001000, // Window is fixed in position even
|
||||
|
||||
SKIP_LIST = 0x00002000, // Not in window list
|
||||
SKIP_FOCUS = 0x00004000 // Skip "Alt+Tab"
|
||||
};
|
||||
|
||||
// values for func and decor flags:
|
||||
enum {
|
||||
// DECOR only:
|
||||
BORDER = 1, // Draw border
|
||||
THIN_BORDER = 2, // Draw thin border
|
||||
TITLEBAR = 4, // Show titlebar
|
||||
SYSMENU = 8, // Show system menu (left on titlebar)
|
||||
|
||||
//FUNC only:
|
||||
MOVE = 16, // Add move action to system menu
|
||||
CLOSE = 32, // Add close action to system menu
|
||||
|
||||
//Common flags:
|
||||
MINIMIZE = 64, // Minimize button and minimize action
|
||||
MAXIMIZE = 128, // Maximize button and maximize action
|
||||
RESIZE = 256 // Resize allowed and resize action
|
||||
};
|
||||
|
||||
// NETWM types
|
||||
enum {
|
||||
TYPE_DESKTOP = 1,
|
||||
TYPE_DOCK,
|
||||
TYPE_TOOLBAR,
|
||||
TYPE_MENU,
|
||||
TYPE_UTIL,
|
||||
TYPE_SPLASH,
|
||||
TYPE_DIALOG,
|
||||
TYPE_NORMAL
|
||||
};
|
||||
|
||||
// values for state_flags:
|
||||
// These change over time
|
||||
enum {
|
||||
IGNORE_UNMAP = 0x01, // we did something that echos an UnmapNotify
|
||||
};
|
||||
|
||||
class Icon;
|
||||
class Desktop;
|
||||
#include "Titlebar.h"
|
||||
|
||||
class Frame : public Fl_Window {
|
||||
friend class Titlebar;
|
||||
friend class ICCCM;
|
||||
friend class MWM;
|
||||
friend class NETWM;
|
||||
|
||||
Titlebar *title;
|
||||
Window window_;
|
||||
|
||||
|
||||
|
||||
|
||||
int wintype; //Type of window (see NETWM types)
|
||||
|
||||
int frame_flags_; // above constant flags
|
||||
short state_; // X server state: iconic, withdrawn, normal
|
||||
short state_flags_; // above state flags
|
||||
short decor_flags_; // Decoration flags from MWM
|
||||
short func_flags_; // Functions flags from MWM
|
||||
|
||||
int restore_x, restore_w; // saved size when min/max width is set
|
||||
int restore_y, restore_h; // saved size when max height is set
|
||||
|
||||
double aspect_min, aspect_max;
|
||||
|
||||
Fl_Rect *strut_;
|
||||
|
||||
MwmHints *mwm_hints;
|
||||
XWMHints *wm_hints;
|
||||
XSizeHints *size_hints;
|
||||
long win_hints;
|
||||
|
||||
Window transient_for_xid; // value from X
|
||||
Frame* transient_for_; // the frame for that xid, if found
|
||||
|
||||
Frame* revert_to; // probably the xterm this was run from
|
||||
|
||||
Colormap colormap; // this window's colormap
|
||||
int colormapWinCount; // list of other windows to install colormaps for
|
||||
Window *colormapWindows;
|
||||
Colormap *window_Colormaps; // their colormaps
|
||||
|
||||
// These are filled if window has icon
|
||||
Icon *icon_;
|
||||
|
||||
Desktop* desktop_;
|
||||
|
||||
int maximize_width();
|
||||
int maximize_height();
|
||||
int force_x_onscreen(int X, int W);
|
||||
int force_y_onscreen(int Y, int H);
|
||||
|
||||
void sendMessage(Atom, Atom) const;
|
||||
|
||||
void send_desktop();
|
||||
void send_configurenotify();
|
||||
void send_state_property();
|
||||
|
||||
void* getProperty(Atom, Atom = AnyPropertyType, unsigned long *length = 0, int *ret=0) const;
|
||||
int getIntProperty(Atom, Atom = AnyPropertyType, int deflt = 0, int *ret = 0) const;
|
||||
void setProperty(Atom, Atom, int) const;
|
||||
void getLabel(bool del = false, Atom from_atom=0);
|
||||
void getColormaps();
|
||||
int getDesktop();
|
||||
|
||||
void updateBorder();
|
||||
void fix_transient_for(); // called when transient_for_xid changes
|
||||
|
||||
void get_protocols();
|
||||
|
||||
void get_wm_hints();
|
||||
void update_wm_hints();
|
||||
|
||||
void get_funcs_from_type();
|
||||
|
||||
void installColormap() const;
|
||||
|
||||
void set_cursor(int);
|
||||
int mouse_location();
|
||||
|
||||
void layout() { Fl_Widget::layout(); }
|
||||
void draw();
|
||||
|
||||
static Frame* active_;
|
||||
void _desktop(Desktop*);
|
||||
|
||||
bool configure_event(const XConfigureRequestEvent *e);
|
||||
bool map_event(const XMapRequestEvent *e);
|
||||
bool unmap_event(const XUnmapEvent *e);
|
||||
bool destroy_event(const XDestroyWindowEvent *e);
|
||||
bool reparent_event(const XReparentEvent *e);
|
||||
bool clientmsg_event(const XClientMessageEvent *e);
|
||||
bool colormap_event(const XColormapEvent *e);
|
||||
bool property_event(const XPropertyEvent *e);
|
||||
bool visibility_event(const XVisibilityEvent *e);
|
||||
bool shape_event(const XShapeEvent *e);
|
||||
|
||||
public:
|
||||
bool shaped;
|
||||
bool get_shape();
|
||||
|
||||
int offset_x, offset_y, offset_w, offset_h;
|
||||
void set_size(int x, int y, int w, int h);
|
||||
|
||||
int frame_flags() const { return frame_flags_; }
|
||||
short decor_flags() const { return decor_flags_; }
|
||||
short func_flags() const { return func_flags_; }
|
||||
short state_flags() const { return state_flags_; }
|
||||
|
||||
bool frame_flag(int i) { return ((frame_flags_&i)==i) ? true : false; }
|
||||
void set_frame_flag(int i) { frame_flags_ |= i; }
|
||||
void clear_frame_flag(int i) { frame_flags_ &=~i; }
|
||||
void clear_frame_flags() { frame_flags_ = 0; }
|
||||
|
||||
bool decor_flag(short i) { return ((decor_flags_&i)==i) ? true : false; }
|
||||
void set_decor_flag(short i) { decor_flags_ |= i; }
|
||||
void clear_decor_flag(short i) { decor_flags_ &=~i; }
|
||||
void clear_decor_flags() { decor_flags_ = 0; }
|
||||
|
||||
bool func_flag(short i) { return ((func_flags_&i)==i) ? true : false; }
|
||||
void set_func_flag(short i) { func_flags_ |= i; }
|
||||
void clear_func_flag(short i) { func_flags_ &=~i; }
|
||||
void clear_func_flags() { func_flags_ = 0; }
|
||||
|
||||
bool state_flag(short i) { return ((state_flags_&i)==i) ? true : false; }
|
||||
void set_state_flag(short i) { state_flags_ |= i; }
|
||||
void clear_state_flag(short i) { state_flags_ &=~i; }
|
||||
void clear_state_flags() { state_flags_ = 0; }
|
||||
|
||||
void cb_button_close(Fl_Button*);
|
||||
void cb_button_kill(Fl_Button*);
|
||||
void cb_button_max(Fl_Button*);
|
||||
void cb_button_min(Fl_Button*);
|
||||
|
||||
int handle(int e); // handle fltk events
|
||||
int handle(const XEvent *e);
|
||||
void handle_move(int &nx, int &ny);
|
||||
|
||||
void window_type(int t) { wintype=t; }
|
||||
int window_type() { return wintype; }
|
||||
|
||||
Frame(Window, XWindowAttributes* = 0);
|
||||
~Frame();
|
||||
|
||||
void destroy_frame();
|
||||
|
||||
void settings_changed();
|
||||
static void settings_changed_all();
|
||||
|
||||
Fl_Rect *strut() { return strut_; }
|
||||
Icon *icon() { return icon_; }
|
||||
|
||||
Window window() const {return window_;}
|
||||
Frame* transient_for() const {return transient_for_;}
|
||||
int is_transient_for(const Frame*) const;
|
||||
|
||||
Desktop* desktop() const {return desktop_;}
|
||||
void desktop(Desktop*);
|
||||
static void desktop(Window wid, int desktop);
|
||||
|
||||
// Wm calls this, when user clicks inside frames
|
||||
void content_click();
|
||||
|
||||
// Raises and put window top of stack
|
||||
void raise();
|
||||
static void raise(Window wid);
|
||||
|
||||
// Lowers and put window back of stack
|
||||
void lower();
|
||||
|
||||
void iconize();
|
||||
void maximize();
|
||||
void restore();
|
||||
|
||||
void throw_focus(int destructor = 0);
|
||||
|
||||
// Closes window with given protocol, if theres no protocol we just kill it
|
||||
static void close(Window wid);
|
||||
void close();
|
||||
void kill();
|
||||
|
||||
// returns true if it actually sets active state(focus)
|
||||
bool activate();
|
||||
bool activate_if_transient();
|
||||
void deactivate();
|
||||
|
||||
// Get or set new state, handles iconizing, mapping and unmapping!
|
||||
short state() const {return state_;}
|
||||
void state(short newstate); // don't call this unless you know what you are doing!
|
||||
|
||||
int active() const {return active_==this;}
|
||||
static Frame* activeFrame() {return active_;}
|
||||
|
||||
static bool do_opaque;
|
||||
static bool focus_follows_mouse;
|
||||
|
||||
static bool animate;
|
||||
static int animate_speed;
|
||||
|
||||
bool maximized;
|
||||
};
|
||||
|
||||
// handy wrappers for those ugly X routines:
|
||||
extern void* getProperty(Window, Atom, Atom = AnyPropertyType, unsigned long* length = 0, int *ret=0);
|
||||
extern int getIntProperty(Window, Atom, Atom = AnyPropertyType, int deflt = 0, int *ret=0);
|
||||
extern void setProperty(Window, Atom, Atom, int);
|
||||
|
||||
extern void draw_overlay(int x, int y, int w, int h);
|
||||
void clear_overlay();
|
||||
|
||||
static inline int max(int a, int b) {return a > b ? a : b;}
|
||||
static inline int min(int a, int b) {return a < b ? a : b;}
|
||||
|
||||
#endif
|
||||
|
280
edewm/Hotkeys.cpp
Normal file
280
edewm/Hotkeys.cpp
Normal file
@ -0,0 +1,280 @@
|
||||
// Hotkeys.cpp
|
||||
// If you want to change what the hotkeys are, see the table at the bottom!
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Frame.h"
|
||||
#include "Windowmanager.h"
|
||||
#include "Desktop.h"
|
||||
|
||||
#include <efltk/Fl_Util.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
extern void show_tabmenu(int dir);
|
||||
|
||||
// Minimize presently active window
|
||||
static void MinimizeWindow(char*)
|
||||
{
|
||||
Frame *act = Frame::activeFrame();
|
||||
int acttype = act->window_type();
|
||||
|
||||
if ((acttype != TYPE_DESKTOP) && (acttype != TYPE_DOCK) && (acttype != TYPE_SPLASH))
|
||||
act->iconize();
|
||||
}
|
||||
|
||||
// Maximize presently active window
|
||||
static void MaximizeWindow(char*)
|
||||
{
|
||||
Frame *act = Frame::activeFrame();
|
||||
int acttype = act->window_type();
|
||||
|
||||
if ((acttype != TYPE_DESKTOP) && (acttype != TYPE_DOCK) && (acttype != TYPE_SPLASH)) {
|
||||
// act->iconize();
|
||||
// FIXME: a function for maximize operation like Frame::iconize()
|
||||
Fl_Button *tmp; // this will never be used
|
||||
act->cb_button_max(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
// Close presently active window
|
||||
static void CloseWindow(char *name)
|
||||
{
|
||||
Frame *act = Frame::activeFrame();
|
||||
int acttype = act->window_type();
|
||||
|
||||
if ((acttype != TYPE_DESKTOP) && (acttype != TYPE_DOCK) && (acttype != TYPE_SPLASH))
|
||||
act->close();
|
||||
}
|
||||
|
||||
// Alt+Tab
|
||||
static void NextWindow(char *name)
|
||||
{
|
||||
show_tabmenu(1);
|
||||
}
|
||||
|
||||
// Alt+Shift+Tab
|
||||
static void PreviousWindow(char *name) {
|
||||
show_tabmenu(-1);
|
||||
}
|
||||
|
||||
// Ctrl+Alt+Right
|
||||
static void NextDesk(char *name)
|
||||
{
|
||||
Desktop::next();
|
||||
}
|
||||
|
||||
// Ctrl+Alt+Left
|
||||
static void PreviousDesk(char *name)
|
||||
{
|
||||
Desktop::prev();
|
||||
}
|
||||
|
||||
// warning: this assummes it is bound to Fn key:
|
||||
static void FKey_DeskNumber(char *name)
|
||||
{
|
||||
int desktop = 1; //Fl::event_key()-0xffbd; // default (bad) way of finding the desktop number
|
||||
// kept for backwards compatibility only
|
||||
|
||||
// new (good) way of finding out the desktop number.
|
||||
// "name" is something like "Desktop1" and we
|
||||
// want to find the "1" on the end
|
||||
if (name) {
|
||||
int val;
|
||||
if (sscanf(name,"Desktop%d",&val) == 1) desktop = val;
|
||||
}
|
||||
|
||||
Desktop::current(Desktop::desktop(desktop));
|
||||
}
|
||||
|
||||
static void FastRun(char *name)
|
||||
{
|
||||
fl_start_child_process("elauncher",false);
|
||||
}
|
||||
|
||||
static void FindUtil(char *name)
|
||||
{
|
||||
fl_start_child_process("efinder",false);
|
||||
}
|
||||
|
||||
static void LaunchApp(char *name)
|
||||
{
|
||||
Fl_Config conf(fl_find_config_file("wmanager.conf", false));
|
||||
Fl_String app;
|
||||
conf.get("Applications", name, app, NULL);
|
||||
if(! app.empty())
|
||||
fl_start_child_process(app, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// I have to take some time to check it out
|
||||
static struct {
|
||||
char *name;
|
||||
int key;
|
||||
void (*func)(char *arg);
|
||||
} keybindings[100]; // hopefully this is enough ;)
|
||||
|
||||
// This function will parse the hotkeys string used in config file,
|
||||
// and construct an integer used by Fl::test_shortcut(int)
|
||||
int parse_hotkey(char *hotkey)
|
||||
{
|
||||
// We do not have *all* possible keys here
|
||||
// (see efltk/efltk/Enumerations.h for more)
|
||||
static struct {
|
||||
char *name;
|
||||
int value;
|
||||
} hotkeys[] = {
|
||||
{"alt", FL_ALT},
|
||||
{"ctrl", FL_CTRL},
|
||||
{"shift", FL_SHIFT},
|
||||
{"win", FL_WIN},
|
||||
{"space", FL_Space},
|
||||
{"backspace", FL_BackSpace},
|
||||
{"tab", FL_Tab},
|
||||
{"enter", FL_Enter},
|
||||
{"escape", FL_Escape},
|
||||
{"home", FL_Home},
|
||||
{"left", FL_Left},
|
||||
{"up", FL_Up},
|
||||
{"right", FL_Right},
|
||||
{"down", FL_Down},
|
||||
{"pageup", FL_Page_Up},
|
||||
{"pagedown", FL_Page_Down},
|
||||
{"end", FL_End},
|
||||
{"insert", FL_Insert},
|
||||
{"delete", FL_Delete},
|
||||
{"f1", FL_F(1)},
|
||||
{"f2", FL_F(2)},
|
||||
{"f3", FL_F(3)},
|
||||
{"f4", FL_F(4)},
|
||||
{"f5", FL_F(5)},
|
||||
{"f6", FL_F(6)},
|
||||
{"f7", FL_F(7)},
|
||||
{"f8", FL_F(8)},
|
||||
{"f9", FL_F(9)},
|
||||
{"f10", FL_F(10)},
|
||||
{"f11", FL_F(11)},
|
||||
{"f12", FL_F(12)},
|
||||
{0, 0}
|
||||
};
|
||||
int parsed = 0;
|
||||
char f[20];
|
||||
|
||||
// The parser - case insensitive and hopefully robust
|
||||
Fl_String_List elements(hotkey, "+");
|
||||
for (uint i=0; i<elements.count(); i++) {
|
||||
bool found = false;
|
||||
for (int j=0; hotkeys[j].value; j++) {
|
||||
Fl_String buf = Fl_String(hotkeys[j].name);
|
||||
if (!elements.item(i).casecmp(buf)) {
|
||||
parsed += hotkeys[j].value;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// use first letter or number as shortcut key
|
||||
strcpy(f, elements.item(i));
|
||||
if ((f[0] >= 'a') && (f[0] <= 'z')) {
|
||||
parsed += f[0];
|
||||
} else if ((f[0] >= 'A') && (f[0] <= 'Z')) {
|
||||
parsed += (f[0] - 'A' + 'a');
|
||||
} else if ((f[0] >= '0') && (f[0] <= '9')) {
|
||||
parsed += f[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
// Read wmanager.conf and initialize an array that will be used later
|
||||
void read_hotkeys_configuration()
|
||||
{
|
||||
// All configurable hotkeys below - edit to add new keys
|
||||
static struct {
|
||||
char *name; // as used in wmanager.conf file
|
||||
void (*func)(char *name); // callback function for this key
|
||||
char *def_key; // default hotkey
|
||||
} configurables[] = {
|
||||
{"PreviousWindow", PreviousWindow, "Alt+Tab"},
|
||||
{"NextWindow", NextWindow, "Alt+Shift+Tab"},
|
||||
{"Desktop1", FKey_DeskNumber, "Alt+F1"},
|
||||
{"Desktop2", FKey_DeskNumber, "Alt+F2"},
|
||||
{"Desktop3", FKey_DeskNumber, "Alt+F3"},
|
||||
{"Desktop4", FKey_DeskNumber, "Alt+F4"},
|
||||
{"Desktop5", FKey_DeskNumber, "Alt+F5"},
|
||||
{"Desktop6", FKey_DeskNumber, "Alt+F6"},
|
||||
{"Desktop7", FKey_DeskNumber, "Alt+F7"},
|
||||
{"Desktop8", FKey_DeskNumber, "Alt+F8"},
|
||||
{"PreviousDesktop", PreviousDesk, "Alt+Ctrl+Right"},
|
||||
{"NextDesktop", NextDesk, "Alt+Ctrl+Left"},
|
||||
{"FindUtil", FindUtil, "Ctrl+F3"},
|
||||
{"FastRun", FastRun, "Ctrl+F12"},
|
||||
{"CloseWindow", CloseWindow, "Ctrl+F4"},
|
||||
{"MinimizeWindow", MinimizeWindow, "Ctrl+F7"},
|
||||
{"MaximizeWindow", MaximizeWindow, "Ctrl+F8"},
|
||||
|
||||
// Slots for user-defined applications and hotkeys
|
||||
// 12 ought to be enough :-)
|
||||
{"App1",LaunchApp,""},
|
||||
{"App2",LaunchApp,""},
|
||||
{"App3",LaunchApp,""},
|
||||
{"App4",LaunchApp,""},
|
||||
{"App5",LaunchApp,""},
|
||||
{"App6",LaunchApp,""},
|
||||
{"App7",LaunchApp,""},
|
||||
{"App8",LaunchApp,""},
|
||||
{"App9",LaunchApp,""},
|
||||
{"App10",LaunchApp,""},
|
||||
{"App11",LaunchApp,""},
|
||||
{"App12",LaunchApp,""},
|
||||
|
||||
{"",NULL,""}
|
||||
};
|
||||
|
||||
char buf[256];
|
||||
int j=0;
|
||||
|
||||
Fl_Config wmconf(fl_find_config_file ("wmanager.conf",0));
|
||||
wmconf.set_section("Hotkeys");
|
||||
|
||||
for (int i=0; configurables[i].name[0]; i++) {
|
||||
wmconf.read(configurables[i].name, buf, configurables[i].def_key, sizeof(buf));
|
||||
if (buf && buf[0]) {
|
||||
keybindings[j].key=parse_hotkey(buf);
|
||||
keybindings[j].name = strdup(configurables[i].name);
|
||||
keybindings[j++].func=configurables[i].func;
|
||||
}
|
||||
}
|
||||
keybindings[j].key = 0;
|
||||
}
|
||||
|
||||
int Handle_Hotkey() {
|
||||
for (int i = 0; keybindings[i].key; i++) {
|
||||
if (Fl::test_shortcut(keybindings[i].key) ||
|
||||
(keybindings[i].key & 0xFFFF) == FL_Delete
|
||||
&& Fl::event_key() == FL_BackSpace// fltk bug?
|
||||
) {
|
||||
keybindings[i].func(keybindings[i].name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Grab_Hotkeys()
|
||||
{
|
||||
Window root_w = fl_xid(root);
|
||||
for (int i = 0; keybindings[i].key; i++) {
|
||||
int k = keybindings[i].key;
|
||||
int keycode = XKeysymToKeycode(fl_display, k & 0xFFFF);
|
||||
if(!keycode) continue;
|
||||
// Silly X! we need to ignore caps lock & numlock keys by grabbing
|
||||
// all the combinations:
|
||||
XGrabKey(fl_display, keycode, k>>16, root_w, 0, 1, 1);
|
||||
XGrabKey(fl_display, keycode, (k>>16)|2, root_w, 0, 1, 1); // CapsLock
|
||||
XGrabKey(fl_display, keycode, (k>>16)|16, root_w, 0, 1, 1); // NumLock
|
||||
XGrabKey(fl_display, keycode, (k>>16)|18, root_w, 0, 1, 1); // both
|
||||
}
|
||||
}
|
207
edewm/Icccm.cpp
Normal file
207
edewm/Icccm.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
#include "Icccm.h"
|
||||
#include "Frame.h"
|
||||
#include "Winhints.h"
|
||||
#include "Windowmanager.h"
|
||||
|
||||
#include <edeconf.h>
|
||||
|
||||
static void icccm_send_state(Window wid, long state)
|
||||
{
|
||||
long data[2];
|
||||
data[0] = state;
|
||||
data[1] = None;
|
||||
XChangeProperty(fl_display, wid, _XA_WM_STATE, _XA_WM_STATE,
|
||||
32, PropModeReplace, (unsigned char *)data, 2);
|
||||
}
|
||||
|
||||
void ICCCM::state_iconic(Frame *f)
|
||||
{
|
||||
icccm_send_state(f->window(), IconicState);
|
||||
}
|
||||
|
||||
void ICCCM::state_normal(Frame *f)
|
||||
{
|
||||
icccm_send_state(f->window(), NormalState);
|
||||
}
|
||||
|
||||
void ICCCM::state_withdrawn(Frame *f)
|
||||
{
|
||||
icccm_send_state(f->window(), WithdrawnState);
|
||||
}
|
||||
|
||||
bool ICCCM::get_size(Frame *f, int &w, int &h)
|
||||
{
|
||||
bool ret=false;
|
||||
int i, j;
|
||||
double aspect;
|
||||
|
||||
XSizeHints *sh = f->size_hints;
|
||||
|
||||
int real_minw = (f->decor_flag(BORDER) || f->decor_flag(THIN_BORDER)) ? 100 : 0;
|
||||
int minw = max(sh->min_width + f->offset_w, real_minw);
|
||||
int minh = sh->min_height+ f->offset_h;
|
||||
|
||||
if(w > sh->max_width) { w = sh->max_width; ret = true; }
|
||||
if(h > sh->max_height) { h = sh->max_height; ret = true; }
|
||||
if(w < minw) { w = minw; ret = true; }
|
||||
if(h < minh) { h = minh; ret = true; }
|
||||
|
||||
if( w>0 && h>0 )
|
||||
{
|
||||
w -= sh->base_width;
|
||||
h -= sh->base_height;
|
||||
if( w>0 && h>0 )
|
||||
{
|
||||
if(f->frame_flag(KEEP_ASPECT)) {
|
||||
aspect = ((double)w) / ((double)h);
|
||||
if (aspect < f->aspect_min)
|
||||
w = (int)((double)h * f->aspect_min);
|
||||
if (aspect > f->aspect_max)
|
||||
h = (int)((double)w / f->aspect_max);
|
||||
}
|
||||
i = w / sh->width_inc;
|
||||
j = h / sh->height_inc;
|
||||
w = i * sh->width_inc;
|
||||
h = j * sh->height_inc;
|
||||
}
|
||||
w += sh->base_width;
|
||||
h += sh->base_height;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ICCCM::configure(Frame *f)
|
||||
{
|
||||
XConfigureEvent ce;
|
||||
ce.send_event = True;
|
||||
ce.display = fl_display;
|
||||
ce.type = ConfigureNotify;
|
||||
ce.event = f->window();
|
||||
ce.window = f->window();
|
||||
ce.x = f->x()+f->offset_x;
|
||||
ce.y = f->y()+f->offset_y;
|
||||
ce.width = f->w()-f->offset_w;
|
||||
ce.height = f->h()-f->offset_h;
|
||||
ce.border_width = f->box()->dx();
|
||||
ce.above = None;
|
||||
ce.override_redirect = False;
|
||||
XSendEvent(fl_display, f->window(), False, StructureNotifyMask, (XEvent*)&ce);
|
||||
}
|
||||
|
||||
void ICCCM::set_iconsizes()
|
||||
{
|
||||
XIconSize *is = XAllocIconSize();
|
||||
|
||||
is->min_width = 8;
|
||||
is->min_height = 8;
|
||||
is->max_width = 48;
|
||||
is->max_height = 48;
|
||||
is->width_inc = 1;
|
||||
is->height_inc = 1;
|
||||
XSetIconSizes(fl_display, root_win, is, 1);
|
||||
|
||||
XFree(is);
|
||||
}
|
||||
|
||||
char *ICCCM::get_title(Frame *f)
|
||||
{
|
||||
XTextProperty xtp;
|
||||
char *title = 0;
|
||||
|
||||
if(XGetWMName(fl_display, f->window(), &xtp))
|
||||
{
|
||||
if(xtp.encoding == XA_STRING) {
|
||||
title = strdup((const char*)xtp.value);
|
||||
} else {
|
||||
#if HAVE_X11_UTF_TEXT_PROP
|
||||
int items;
|
||||
char **list=0;
|
||||
Status s;
|
||||
s = Xutf8TextPropertyToTextList(fl_display, &xtp, &list, &items);
|
||||
if((s == Success) && (items > 0)) {
|
||||
title = strdup((const char *)*list);
|
||||
} else
|
||||
title = strdup((const char *)xtp.value);
|
||||
if(list) XFreeStringList(list);
|
||||
#else
|
||||
title = strdup((const char*)xtp.value);
|
||||
#endif
|
||||
}
|
||||
XFree(xtp.value);
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
// Read the sizeHints to size_hints object
|
||||
// Returns true if autoplace should be done.
|
||||
bool ICCCM::size_hints(Frame *f)
|
||||
{
|
||||
long supplied;
|
||||
|
||||
XSizeHints *size_hints = f->size_hints;
|
||||
|
||||
if(!XGetWMNormalHints(fl_display, f->window(), size_hints, &supplied))
|
||||
size_hints->flags = 0;
|
||||
|
||||
if(size_hints->flags & PResizeInc) {
|
||||
if(size_hints->width_inc < 1) size_hints->width_inc = 1;
|
||||
if(size_hints->height_inc < 1) size_hints->height_inc = 1;
|
||||
} else
|
||||
size_hints->width_inc = size_hints->height_inc = 1;
|
||||
|
||||
if(!(size_hints->flags & PBaseSize)) {
|
||||
if (size_hints->flags & PMinSize) {
|
||||
size_hints->base_width = size_hints->min_width;
|
||||
size_hints->base_height = size_hints->min_height;
|
||||
} else
|
||||
size_hints->base_width = size_hints->base_height = 0;
|
||||
}
|
||||
|
||||
if(!(size_hints->flags & PMinSize)) {
|
||||
size_hints->min_width = size_hints->base_width;
|
||||
size_hints->min_height = size_hints->base_height;
|
||||
}
|
||||
|
||||
if(!(size_hints->flags & PMaxSize)) {
|
||||
size_hints->max_width = 32767;
|
||||
size_hints->max_height = 32767;
|
||||
}
|
||||
|
||||
if (size_hints->min_height <= 0)
|
||||
size_hints->min_height = 1;
|
||||
if (size_hints->min_width <= 0)
|
||||
size_hints->min_width = 1;
|
||||
|
||||
if(size_hints->max_width<size_hints->min_width || size_hints->max_width<=0)
|
||||
size_hints->max_width = 32767;
|
||||
if(size_hints->max_height<size_hints->min_height || size_hints->max_height<=0)
|
||||
size_hints->max_height = 32767;
|
||||
|
||||
if(!(size_hints->flags & PWinGravity)) {
|
||||
size_hints->win_gravity = NorthWestGravity;
|
||||
size_hints->flags |= PWinGravity;
|
||||
}
|
||||
|
||||
if(size_hints->flags & PAspect) {
|
||||
f->set_frame_flag(KEEP_ASPECT);
|
||||
if((size_hints->min_aspect.y > 0.0) && (size_hints->min_aspect.x > 0.0)) {
|
||||
f->aspect_min = ((double)size_hints->min_aspect.x) / ((double)size_hints->min_aspect.y);
|
||||
} else {
|
||||
f->aspect_min = 0.0;
|
||||
}
|
||||
if((size_hints->max_aspect.y > 0.0) && (size_hints->max_aspect.x > 0.0)) {
|
||||
f->aspect_max = ((double)size_hints->max_aspect.x) / ((double)size_hints->max_aspect.y);
|
||||
} else {
|
||||
f->aspect_max = 32767.0;
|
||||
}
|
||||
} else {
|
||||
f->aspect_min = 0.0;
|
||||
f->aspect_max = 32767.0;
|
||||
}
|
||||
|
||||
// fix for old gimp, which sets PPosition to 0,0:
|
||||
// if(f->x() <= 0 && f->y() <= 0) size_hints->flags &= ~PPosition;
|
||||
|
||||
return !(size_hints->flags & (USPosition|PPosition));
|
||||
}
|
||||
|
23
edewm/Icccm.h
Normal file
23
edewm/Icccm.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _ICCCM_H_
|
||||
#define _ICCCM_H_
|
||||
|
||||
class Frame;
|
||||
|
||||
class ICCCM
|
||||
{
|
||||
public:
|
||||
static void state_iconic(Frame *f);
|
||||
static void state_normal(Frame *f);
|
||||
static void state_withdrawn(Frame *f);
|
||||
|
||||
static void configure(Frame *f);
|
||||
static void set_iconsizes();
|
||||
|
||||
static bool get_size(Frame *f, int &w, int &h);
|
||||
static char *get_title(Frame *f);
|
||||
|
||||
static bool size_hints(Frame *f);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
165
edewm/Icon.cpp
Normal file
165
edewm/Icon.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
#include "Icon.h"
|
||||
#include "debug.h"
|
||||
|
||||
// Default icon
|
||||
#include "tux.xpm"
|
||||
|
||||
#define I(i) ((Fl_Image*)i)
|
||||
|
||||
static Fl_Image default_icon(tux_xpm);
|
||||
|
||||
uint8 *cvt1to32(XImage *xim, int ow, int oh)
|
||||
{
|
||||
int pixel;
|
||||
int pitch = Fl_Renderer::calc_pitch(4, ow);
|
||||
uint8 *data = new uint8[oh*pitch];
|
||||
uint32 *ptr;
|
||||
int x,y;
|
||||
for(y = 0; y < oh; y++)
|
||||
{
|
||||
ptr = (uint32*) (data + (pitch*y));
|
||||
for(x = 0; x < ow; x++) {
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
if(pixel) *ptr++ = 0x00000000;
|
||||
else *ptr++ = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
extern uint8 *ximage_to_data(XImage *im, Fl_PixelFormat *desired);
|
||||
|
||||
Icon::Icon(XWMHints *wm_hints)
|
||||
{
|
||||
// Max size 128x128
|
||||
Fl_Rect r(0, 0, 128, 128);
|
||||
XImage *xim;
|
||||
|
||||
image=0;
|
||||
mask=0;
|
||||
|
||||
// ICON
|
||||
if(wm_hints && wm_hints->flags & IconPixmapHint && wm_hints->icon_pixmap)
|
||||
{
|
||||
xim = Fl_Renderer::ximage_from_pixmap(wm_hints->icon_pixmap, r);
|
||||
if(xim)
|
||||
{
|
||||
Fl_PixelFormat fmt;
|
||||
|
||||
DBG("Icon format: %dx%d %d\n",xim->width, xim->height, xim->depth);
|
||||
DBG("depth/padding: %d/%d; r/g/b mask: %lx/%lx/%lx\n",
|
||||
xim->depth, xim->bitmap_pad,
|
||||
xim->red_mask, xim->green_mask, xim->blue_mask);
|
||||
|
||||
uint8 *data=0;
|
||||
if(xim->depth==1) {
|
||||
data = cvt1to32(xim, xim->width, xim->height);
|
||||
fmt.realloc(32,0xFF0000,0x00FF00,0x0000FF,0);
|
||||
} else {
|
||||
data = ximage_to_data(xim, Fl_Renderer::system_format());
|
||||
fmt.copy(Fl_Renderer::system_format());
|
||||
}
|
||||
|
||||
// Create Fl_Image, masks are calculated automaticly
|
||||
image = new Fl_Image(xim->width, xim->height, &fmt, data);
|
||||
image->mask_type(FL_MASK_NONE);
|
||||
XDestroyImage(xim);
|
||||
}
|
||||
}
|
||||
|
||||
// MASK
|
||||
if(wm_hints && image && wm_hints->flags & IconMaskHint && wm_hints->icon_mask)
|
||||
{
|
||||
xim = Fl_Renderer::ximage_from_pixmap(wm_hints->icon_mask, r);
|
||||
if(xim) {
|
||||
uint8 *data = cvt1to32(xim, xim->width, xim->height);
|
||||
mask = new Fl_Image(xim->width, xim->height, 32, data, 0,0,0,0);
|
||||
mask->no_screen(true);
|
||||
XDestroyImage(xim);
|
||||
}
|
||||
}
|
||||
|
||||
// If no icon, set default
|
||||
if(!image) {
|
||||
image = &default_icon;
|
||||
mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Icon::~Icon()
|
||||
{
|
||||
if(image && image!=&default_icon) { delete image; image=0; }
|
||||
if(mask) { delete mask; mask=0; }
|
||||
|
||||
for(ImageMap::Iterator it(images); it.current(); it++) {
|
||||
Fl_Image *i = I(it.value());
|
||||
if(i && i!=&default_icon) {
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fl_Image *Icon::get_icon(int W, int H)
|
||||
{
|
||||
if (!image) return 0;
|
||||
|
||||
Fl_Image *scaled=0, *cached=0;
|
||||
|
||||
Fl_String key;
|
||||
key += Fl_String(W);
|
||||
key += 'x';
|
||||
key += Fl_String(H);
|
||||
|
||||
if(image==&default_icon)
|
||||
{
|
||||
if(W!=image->width() || H!=image->height())
|
||||
{
|
||||
cached = I(images.get_value(key));
|
||||
if(cached) {
|
||||
//printf("1. Cached\n");
|
||||
return cached;
|
||||
}
|
||||
|
||||
scaled = image->scale(W, H);
|
||||
scaled->set_mask(default_icon.create_scaled_bitmap_mask(W, H), true);
|
||||
images.insert(key, scaled);
|
||||
return scaled;
|
||||
|
||||
} else
|
||||
return image;
|
||||
}
|
||||
|
||||
cached = I(images.get_value(key));
|
||||
if(cached) {
|
||||
//printf("2. Cached\n");
|
||||
return cached;
|
||||
}
|
||||
|
||||
// Check for default size image
|
||||
if(W==image->width() && H==image->height()) {
|
||||
if(mask && mask->get_mask()==0) {
|
||||
// Init mask
|
||||
mask->mask_type(MASK_COLORKEY);
|
||||
mask->colorkey(0xFFFFFFFF);
|
||||
Pixmap m = mask->create_mask(W, H);
|
||||
mask->set_mask(m, true);
|
||||
image->set_mask(mask->get_mask());
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
// Create NEW
|
||||
scaled = image->scale(W,H);
|
||||
if(mask) {
|
||||
Fl_Image *smask = mask->scale(W, H);
|
||||
smask->mask_type(MASK_COLORKEY);
|
||||
smask->colorkey(0xFFFFFFFF);
|
||||
Pixmap m = smask->create_mask(W, H);
|
||||
delete smask;
|
||||
scaled->set_mask(m, true);
|
||||
}
|
||||
|
||||
images.insert(key, scaled);
|
||||
return scaled;
|
||||
}
|
||||
|
26
edewm/Icon.h
Normal file
26
edewm/Icon.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef _ICON_H_
|
||||
#define _ICON_H_
|
||||
|
||||
#include "Frame.h"
|
||||
|
||||
#include <efltk/Fl_Image.h>
|
||||
#include <efltk/Fl_Renderer.h>
|
||||
#include <efltk/Fl_Map.h>
|
||||
|
||||
typedef Fl_String_Ptr_Map ImageMap;
|
||||
|
||||
class Icon
|
||||
{
|
||||
public:
|
||||
Icon(XWMHints *wm_hints);
|
||||
~Icon();
|
||||
|
||||
Fl_Image *get_icon(int W, int H);
|
||||
|
||||
private:
|
||||
ImageMap images;
|
||||
Fl_Image *image, *mask;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
49
edewm/Makefile
Normal file
49
edewm/Makefile
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# $Id: Makefile 1957 2007-06-25 19:42:47Z vljubovic $
|
||||
#
|
||||
# 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.
|
||||
|
||||
CPPFILES = WMWindow.cpp\
|
||||
Theme.cpp\
|
||||
Netwm.cpp\
|
||||
Mwm.cpp\
|
||||
Icccm.cpp\
|
||||
Icon.cpp\
|
||||
Cursor.cpp\
|
||||
Desktop.cpp\
|
||||
Events.cpp\
|
||||
Frame.cpp\
|
||||
Hotkeys.cpp\
|
||||
Tabmenu.cpp\
|
||||
Titlebar.cpp\
|
||||
Windowmanager.cpp\
|
||||
Winhints.cpp\
|
||||
main.cpp
|
||||
|
||||
TARGET = edewm
|
||||
|
||||
POFILES = locale/ru.po\
|
||||
locale/sr.po\
|
||||
locale/sk.po\
|
||||
locale/hu.po\
|
||||
locale/de.po\
|
||||
locale/fr.po
|
||||
|
||||
include ../makeinclude
|
||||
|
||||
install:
|
||||
$(INSTALL_PROGRAM) $(TARGET) $(bindir)
|
||||
$(INSTALL_LOCALE)
|
||||
|
||||
uninstall:
|
||||
$(RM) $(bindir)/$(TARGET)
|
||||
|
||||
clean:
|
||||
$(RM) $(TARGET)
|
||||
$(RM) *.o
|
||||
|
191
edewm/Mwm.cpp
Normal file
191
edewm/Mwm.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
#include "Mwm.h"
|
||||
#include "Frame.h"
|
||||
#include "Winhints.h"
|
||||
#include "Windowmanager.h"
|
||||
|
||||
void MWM::get_hints(Frame *f)
|
||||
{
|
||||
if(f->mwm_hints) {
|
||||
XFree((char *)f->mwm_hints);
|
||||
f->mwm_hints = 0;
|
||||
}
|
||||
|
||||
unsigned long n=0;
|
||||
f->mwm_hints = (MwmHints *)getProperty(f->window(), _XATOM_MWM_HINTS, _XATOM_MWM_HINTS, &n);
|
||||
|
||||
if(n >= PROP_MWM_HINTS_ELEMENTS) {
|
||||
// Fill in the default value for missing fields:
|
||||
if(!(f->mwm_hints->flags & MWM_HINTS_FUNCTIONS))
|
||||
f->mwm_hints->functions = MWM_FUNC_ALL;
|
||||
if(!(f->mwm_hints->flags & MWM_HINTS_DECORATIONS))
|
||||
f->mwm_hints->decorations = MWM_DECOR_ALL;
|
||||
} else {
|
||||
XFree((char *)f->mwm_hints);
|
||||
f->mwm_hints = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static long mwm_functions(MwmHints *hints, XSizeHints *sh)
|
||||
{
|
||||
long functions = ~0U;
|
||||
|
||||
if(hints && (hints->flags & MWM_HINTS_FUNCTIONS))
|
||||
{
|
||||
if(hints->functions & MWM_FUNC_ALL)
|
||||
functions = ~hints->functions;
|
||||
else
|
||||
functions = hints->functions;
|
||||
|
||||
} else {
|
||||
|
||||
if(sh) {
|
||||
bool minmax = false;
|
||||
if(sh->min_width == sh->max_width && sh->min_height == sh->max_height) {
|
||||
functions &= ~MWM_FUNC_RESIZE;
|
||||
minmax = true;
|
||||
}
|
||||
if((minmax && !(sh->flags & PResizeInc)) ||
|
||||
(sh->width_inc == 0 && sh->height_inc == 0))
|
||||
functions &= ~MWM_FUNC_MAXIMIZE;
|
||||
}
|
||||
}
|
||||
functions &= (MWM_FUNC_RESIZE | MWM_FUNC_MOVE |
|
||||
MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE |
|
||||
MWM_FUNC_CLOSE);
|
||||
return functions;
|
||||
}
|
||||
|
||||
static long mwm_decors(MwmHints *hints, XSizeHints *sh)
|
||||
{
|
||||
long decors = ~0U;
|
||||
long func = mwm_functions(hints, sh);
|
||||
|
||||
if(hints && (hints->flags & MWM_HINTS_DECORATIONS)) {
|
||||
if(hints->decorations & MWM_DECOR_ALL)
|
||||
decors = ~hints->decorations;
|
||||
else
|
||||
decors = hints->decorations;
|
||||
|
||||
} else {
|
||||
|
||||
if(sh) {
|
||||
bool minmax = false;
|
||||
if(sh->min_width == sh->max_width && sh->min_height == sh->max_height) {
|
||||
decors &= ~MWM_DECOR_RESIZEH;
|
||||
minmax = true;
|
||||
}
|
||||
if((minmax && !(sh->flags & PResizeInc)) ||
|
||||
(sh->width_inc == 0 && sh->height_inc == 0))
|
||||
decors &= ~MWM_DECOR_MAXIMIZE;
|
||||
}
|
||||
}
|
||||
decors &= (MWM_DECOR_BORDER | MWM_DECOR_RESIZEH |
|
||||
MWM_DECOR_TITLE | MWM_DECOR_MENU |
|
||||
MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE);
|
||||
|
||||
// Add disabled buttons !!!
|
||||
decors &=
|
||||
~(/*((func & MWM_FUNC_RESIZE) ? 0 : MWM_DECOR_RESIZEH) |*/
|
||||
((func & MWM_FUNC_MINIMIZE) ? 0 : MWM_DECOR_MINIMIZE) |
|
||||
((func & MWM_FUNC_MAXIMIZE) ? 0 : MWM_DECOR_MAXIMIZE));
|
||||
|
||||
return decors;
|
||||
}
|
||||
|
||||
bool MWM::update_hints(Frame *f)
|
||||
{
|
||||
MwmHints *mwm_hints = f->mwm_hints;
|
||||
XSizeHints *size_hints = f->size_hints;
|
||||
|
||||
long decors = mwm_decors(mwm_hints, size_hints);
|
||||
long functions = mwm_functions(mwm_hints, size_hints);
|
||||
|
||||
bool funcs_only = (mwm_hints &&
|
||||
(mwm_hints->flags & (MWM_HINTS_FUNCTIONS) == MWM_HINTS_FUNCTIONS) &&
|
||||
(mwm_hints->flags & (MWM_HINTS_DECORATIONS) != MWM_HINTS_DECORATIONS)
|
||||
);
|
||||
|
||||
// The low bit means "turn the marked items off", invert this.
|
||||
// Transient windows already have size & iconize buttons turned off:
|
||||
if(functions & MWM_FUNC_ALL)
|
||||
functions = ~functions & (f->transient_for_xid ? ~0x58 : -1);
|
||||
if(decors & MWM_DECOR_ALL)
|
||||
decors = ~decors & (f->transient_for_xid ? ~0x60 : -1);
|
||||
|
||||
int old_decor_flags = f->decor_flags();
|
||||
int old_func_flags = f->func_flags();
|
||||
int old_frame_flags = f->frame_flags();
|
||||
|
||||
// Get decorations
|
||||
f->clear_decor_flags();
|
||||
if(decors & MWM_DECOR_BORDER)
|
||||
f->set_decor_flag(BORDER);
|
||||
if(decors & MWM_DECOR_TITLE)
|
||||
f->set_decor_flag(TITLEBAR);
|
||||
if(decors & MWM_DECOR_MENU)
|
||||
f->set_decor_flag(SYSMENU);
|
||||
if(decors & MWM_DECOR_MINIMIZE)
|
||||
f->set_decor_flag(MINIMIZE);
|
||||
if(decors & MWM_DECOR_MAXIMIZE)
|
||||
f->set_decor_flag(MAXIMIZE);
|
||||
if(decors & MWM_DECOR_RESIZEH)
|
||||
f->set_decor_flag(RESIZE);
|
||||
|
||||
// Get functions
|
||||
f->clear_func_flags();
|
||||
if(functions & MWM_FUNC_RESIZE) {
|
||||
f->set_func_flag(RESIZE);
|
||||
if(funcs_only) f->set_decor_flag(RESIZE|BORDER);
|
||||
}
|
||||
if(functions & MWM_FUNC_MOVE) {
|
||||
f->set_func_flag(MOVE);
|
||||
if(funcs_only) f->set_decor_flag(BORDER);
|
||||
}
|
||||
if(functions & MWM_FUNC_MINIMIZE) {
|
||||
f->set_func_flag(MINIMIZE);
|
||||
if(funcs_only) f->set_decor_flag(MINIMIZE);
|
||||
}
|
||||
if(functions & MWM_FUNC_MAXIMIZE) {
|
||||
f->set_func_flag(MAXIMIZE);
|
||||
if(funcs_only) f->set_decor_flag(MAXIMIZE);
|
||||
}
|
||||
if(functions & MWM_FUNC_CLOSE) {
|
||||
f->set_func_flag(CLOSE);
|
||||
f->set_decor_flag(CLOSE);
|
||||
}
|
||||
|
||||
// some Motif programs use this to disable resize :-(
|
||||
// and some programs change this after the window is shown (*&%$#%)
|
||||
if(!(functions & MWM_FUNC_RESIZE) || !(decors & MWM_DECOR_RESIZEH))
|
||||
f->clear_decor_flag(RESIZE);
|
||||
else
|
||||
f->set_decor_flag(RESIZE);
|
||||
|
||||
// and some use this to disable the Close function. The commented
|
||||
// out test is it trying to turn off the mwm menu button: it appears
|
||||
// programs that do that still expect Alt+F4 to close them, so I
|
||||
// leave the close on then:
|
||||
if (!(functions & 0x20) /*|| !(prop[2]&0x10)*/) {
|
||||
f->clear_func_flag(CLOSE);
|
||||
f->clear_decor_flag(CLOSE);
|
||||
} else {
|
||||
f->set_func_flag(CLOSE);
|
||||
f->set_decor_flag(CLOSE);
|
||||
}
|
||||
|
||||
// Set modal
|
||||
if(!f->shown() && mwm_hints && (mwm_hints->flags & MWM_HINTS_INPUT_MODE) && (mwm_hints->input_mode != MWM_INPUT_MODELESS))
|
||||
f->set_frame_flag(MODAL);
|
||||
|
||||
return ((f->frame_flags() ^ old_frame_flags) || (f->decor_flags() ^ old_decor_flags) || (f->func_flags() ^ old_func_flags));
|
||||
}
|
||||
|
||||
void MWM::set_motif_info()
|
||||
{
|
||||
MotifWmInfo mwminfo;
|
||||
mwminfo.flags = MWM_INFO_STARTUP_CUSTOM;
|
||||
mwminfo.wm_window = root_win;
|
||||
XChangeProperty(fl_display, root_win, _XATOM_MOTIF_WM_INFO, _XATOM_MOTIF_WM_INFO,
|
||||
32, PropModeReplace,
|
||||
(unsigned char *)&mwminfo, 2);
|
||||
}
|
83
edewm/Mwm.h
Normal file
83
edewm/Mwm.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef _MWM_H_
|
||||
#define _MWM_H_
|
||||
|
||||
#include <X11/Xmd.h>
|
||||
#include <X11/Xlib.h>
|
||||
/* This file is part of the GNU LessTif Library. */
|
||||
|
||||
typedef struct {
|
||||
long flags;
|
||||
Window wm_window;
|
||||
} MotifWmInfo;
|
||||
|
||||
#define MWM_INFO_STARTUP_STANDARD (1L<<0)
|
||||
#define MWM_INFO_STARTUP_CUSTOM (1L<<1)
|
||||
|
||||
typedef struct {
|
||||
unsigned long flags;
|
||||
unsigned long functions;
|
||||
unsigned long decorations;
|
||||
long input_mode;
|
||||
unsigned long status;
|
||||
} MwmHints;
|
||||
|
||||
#define MWM_HINTS_FUNCTIONS (1L << 0)
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
#define MWM_HINTS_INPUT_MODE (1L << 2)
|
||||
#define MWM_HINTS_STATUS (1L << 3)
|
||||
|
||||
#define MWM_FUNC_ALL (1L << 0)
|
||||
#define MWM_FUNC_RESIZE (1L << 1)
|
||||
#define MWM_FUNC_MOVE (1L << 2)
|
||||
#define MWM_FUNC_MINIMIZE (1L << 3)
|
||||
#define MWM_FUNC_MAXIMIZE (1L << 4)
|
||||
#define MWM_FUNC_CLOSE (1L << 5)
|
||||
|
||||
#define MWM_DECOR_ALL (1L << 0)
|
||||
#define MWM_DECOR_BORDER (1L << 1)
|
||||
#define MWM_DECOR_RESIZEH (1L << 2)
|
||||
#define MWM_DECOR_TITLE (1L << 3)
|
||||
#define MWM_DECOR_MENU (1L << 4)
|
||||
#define MWM_DECOR_MINIMIZE (1L << 5)
|
||||
#define MWM_DECOR_MAXIMIZE (1L << 6)
|
||||
|
||||
#define MWM_INPUT_MODELESS 0
|
||||
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
|
||||
#define MWM_INPUT_SYSTEM_MODAL 2
|
||||
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
|
||||
#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
|
||||
|
||||
#define MWM_TEAROFF_WINDOW (1L<<0)
|
||||
|
||||
/*
|
||||
* atoms
|
||||
*/
|
||||
#define _XA_MOTIF_BINDINGS "_MOTIF_BINDINGS"
|
||||
#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS"
|
||||
#define _XA_MOTIF_WM_MESSAGES "_MOTIF_WM_MESSAGES"
|
||||
#define _XA_MOTIF_WM_OFFSET "_MOTIF_WM_OFFSET"
|
||||
#define _XA_MOTIF_WM_MENU "_MOTIF_WM_MENU"
|
||||
#define _XA_MOTIF_WM_INFO "_MOTIF_WM_INFO"
|
||||
#define _XA_MWM_HINTS _XA_MOTIF_WM_HINTS
|
||||
#define _XA_MWM_MESSAGES _XA_MOTIF_WM_MESSAGES
|
||||
#define _XA_MWM_MENU _XA_MOTIF_WM_MENU
|
||||
#define _XA_MWM_INFO _XA_MOTIF_WM_INFO
|
||||
|
||||
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
|
||||
#define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS
|
||||
|
||||
////////////////////////////////////
|
||||
|
||||
class Frame;
|
||||
|
||||
class MWM
|
||||
{
|
||||
public:
|
||||
static void get_hints(Frame *f);
|
||||
static bool update_hints(Frame *f);
|
||||
|
||||
static void set_motif_info();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
116
edewm/Netwm.cpp
Normal file
116
edewm/Netwm.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include "Netwm.h"
|
||||
#include "Frame.h"
|
||||
#include "Winhints.h"
|
||||
#include "Windowmanager.h"
|
||||
#include "debug.h"
|
||||
|
||||
void NETWM::get_strut(Frame *f)
|
||||
{
|
||||
unsigned long size = 0;
|
||||
CARD32 *val=0;
|
||||
|
||||
val = (CARD32 *)getProperty(f->window(), _XA_NET_WM_STRUT, XA_CARDINAL, &size);
|
||||
if(!val) return;
|
||||
|
||||
if ((size / (sizeof(CARD32))) != 4) {
|
||||
DBG("Window 0x%lx has wrong STRUT value (%d)\n", f->window(), size / (sizeof(CARD32)));
|
||||
XFree((char*)val);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!f->strut_) f->strut_ = new Fl_Rect();
|
||||
|
||||
int l=val[0];
|
||||
int r=val[1];
|
||||
int t=val[2];
|
||||
int b=val[3];
|
||||
f->strut_->set(l, t, l+r, t+b);
|
||||
|
||||
XFree((char*)val);
|
||||
}
|
||||
|
||||
bool NETWM::get_window_type(Frame *f)
|
||||
{
|
||||
unsigned long size = 0;
|
||||
Atom *val=0;
|
||||
int ret=0;
|
||||
int wintype = TYPE_NORMAL;
|
||||
|
||||
val = (Atom *)getProperty(f->window(), _XA_NET_WM_WINDOW_TYPE, XA_ATOM, &size, &ret);
|
||||
if(!val || ret!=Success) {
|
||||
f->window_type(TYPE_NORMAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
for(uint i = 0; i < (size / (sizeof(Atom))); i++)
|
||||
{
|
||||
if (val[i] == _XA_NET_WM_WINDOW_TYPE_DOCK)
|
||||
{
|
||||
DBG("_XA_NET_WM_WINDOW_TYPE_DOCK\n");
|
||||
wintype = TYPE_DOCK;
|
||||
break;
|
||||
}
|
||||
else if (val[i] == _XA_NET_WM_WINDOW_TYPE_TOOLBAR)
|
||||
{
|
||||
DBG("_XA_NET_WM_WINDOW_TYPE_TOOLBAR\n");
|
||||
wintype = TYPE_TOOLBAR;
|
||||
break;
|
||||
}
|
||||
else if (val[i] == _XA_NET_WM_WINDOW_TYPE_MENU)
|
||||
{
|
||||
DBG("_XA_NET_WM_WINDOW_TYPE_MENU\n");
|
||||
wintype = TYPE_MENU;
|
||||
break;
|
||||
}
|
||||
else if (val[i] == _XA_NET_WM_WINDOW_TYPE_UTIL)
|
||||
{
|
||||
DBG("_XA_NET_WM_WINDOW_TYPE_UTIL\n");
|
||||
wintype = TYPE_UTIL;
|
||||
break;
|
||||
}
|
||||
else if (val[i] == _XA_NET_WM_WINDOW_TYPE_DIALOG)
|
||||
{
|
||||
DBG("_XA_NET_WM_WINDOW_TYPE_DIALOG\n");
|
||||
wintype = TYPE_DIALOG;
|
||||
break;
|
||||
}
|
||||
else if (val[i] == _XA_NET_WM_WINDOW_TYPE_NORMAL)
|
||||
{
|
||||
DBG("_XA_NET_WM_WINDOW_TYPE_NORMAL\n");
|
||||
wintype = TYPE_NORMAL;
|
||||
break;
|
||||
}
|
||||
else if (val[i] == _XA_NET_WM_WINDOW_TYPE_DESKTOP)
|
||||
{
|
||||
DBG("_XA_NET_WM_WINDOW_TYPE_DESKTOP\n");
|
||||
wintype = TYPE_DESKTOP;
|
||||
break;
|
||||
} else {
|
||||
DBG("Unknown NETWM window type 0x%08lx\n", val[i]);
|
||||
}
|
||||
|
||||
} /* for */
|
||||
|
||||
XFree((char*)val);
|
||||
|
||||
f->window_type(wintype);
|
||||
return true;
|
||||
}
|
||||
|
||||
void NETWM::set_active_window(Window win)
|
||||
{
|
||||
//Set NET-WM active window
|
||||
XChangeProperty(fl_display, root_win, _XA_NET_ACTIVE_WINDOW, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)&win, 1);
|
||||
}
|
||||
|
||||
char *NETWM::get_title(Frame *f)
|
||||
{
|
||||
int ret=0;
|
||||
char *title = (char*)getProperty(f->window(), _XA_NET_WM_NAME, _XA_UTF8_STRING, 0, &ret);
|
||||
if(!title || ret!=Success) {
|
||||
return 0;
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
17
edewm/Netwm.h
Normal file
17
edewm/Netwm.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _NETWM_H_
|
||||
#define _NETWM_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
class Frame;
|
||||
|
||||
class NETWM
|
||||
{
|
||||
public:
|
||||
static void get_strut(Frame *f);
|
||||
static bool get_window_type(Frame *f);
|
||||
static char *get_title(Frame *f);
|
||||
|
||||
static void set_active_window(Window win);
|
||||
};
|
||||
|
||||
#endif
|
201
edewm/Tabmenu.cpp
Normal file
201
edewm/Tabmenu.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
//nothing yet!
|
||||
|
||||
#include <efltk/Fl_Box.h>
|
||||
#include <efltk/Fl_Pack.h>
|
||||
|
||||
#include "Icon.h"
|
||||
#include "Frame.h"
|
||||
#include "Desktop.h"
|
||||
#include "debug.h"
|
||||
#include "Windowmanager.h"
|
||||
|
||||
class TabWin : public Fl_Window
|
||||
{
|
||||
public:
|
||||
TabWin(Frame_List &list, int dir) : Fl_Window(Fl::w()/2-100, Fl::h()/2-40, 200, 96, "tabwin")
|
||||
{
|
||||
direction = dir;
|
||||
selected=-1;
|
||||
box(FL_UP_BOX);
|
||||
|
||||
label = new Fl_Box(10,50,180,20);
|
||||
label->box(FL_THIN_DOWN_BOX);
|
||||
label->align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
|
||||
|
||||
p = new Fl_Pack(0,0,200,50);
|
||||
p->type(Fl_Pack::HORIZONTAL);
|
||||
p->layout_spacing(3);
|
||||
p->begin();
|
||||
|
||||
for(uint n=0; n<list.size(); n++) {
|
||||
Frame *f = list[n];
|
||||
Fl_Box *b = new Fl_Box(0,0,50,50,f->label());
|
||||
b->color(FL_GRAY);
|
||||
b->layout_align(FL_ALIGN_LEFT);
|
||||
b->user_data(f);
|
||||
b->label_type(FL_NO_LABEL);
|
||||
b->box(FL_BORDER_BOX);
|
||||
if(f->icon()) {
|
||||
b->image(f->icon()->get_icon(48,48));
|
||||
}
|
||||
if(f->active())
|
||||
{
|
||||
selected = n;
|
||||
b->set_selected();
|
||||
b->color(FL_RED);
|
||||
b->box(FL_THIN_DOWN_BOX);
|
||||
label->label(f->label());
|
||||
}
|
||||
}
|
||||
p->end();
|
||||
|
||||
layout();
|
||||
create();
|
||||
}
|
||||
|
||||
void next() {
|
||||
if(selected==-1) selected=0;
|
||||
if(p->child(selected)->selected())
|
||||
p->child(selected)->clear_selected();
|
||||
|
||||
p->child(selected)->color(FL_GRAY);
|
||||
p->child(selected)->box(FL_BORDER_BOX);
|
||||
selected += direction;
|
||||
if(direction==1 && selected>=p->children()) {
|
||||
selected = 0;
|
||||
}
|
||||
else if(direction==-1 && selected<0) {
|
||||
selected = p->children()-1;
|
||||
}
|
||||
|
||||
p->child(selected)->set_selected();
|
||||
p->child(selected)->color(p->selection_color());
|
||||
p->child(selected)->box(FL_THIN_DOWN_BOX);
|
||||
|
||||
label->label(p->child(selected)->label());
|
||||
|
||||
redraw(FL_DAMAGE_ALL);
|
||||
}
|
||||
Frame *selected_frame() {
|
||||
if(selected==-1) return 0;
|
||||
return (Frame *)p->child(selected)->user_data();
|
||||
}
|
||||
|
||||
int handle(int ev);
|
||||
void layout();
|
||||
|
||||
void draw();
|
||||
|
||||
Fl_Pack *p;
|
||||
Fl_Box *label;
|
||||
int selected;
|
||||
int direction;
|
||||
};
|
||||
|
||||
TabWin *win=0;
|
||||
|
||||
int TabWin::handle(int ev)
|
||||
{
|
||||
return Fl_Window::handle(ev);
|
||||
}
|
||||
|
||||
void TabWin::draw()
|
||||
{
|
||||
if(damage()&FL_DAMAGE_ALL || damage()&FL_DAMAGE_EXPOSE) {
|
||||
Fl_Window::draw();
|
||||
}
|
||||
}
|
||||
|
||||
void TabWin::layout()
|
||||
{
|
||||
p->layout();
|
||||
int w = p->w()+20;
|
||||
if(w<300) w=300;
|
||||
|
||||
int h=100;
|
||||
|
||||
int x = Fl::w()/2-(w/2);
|
||||
int y = Fl::h()/2-(h/2);
|
||||
|
||||
resize(x, y, w, h);
|
||||
p->resize(10, 10, p->w(), 50);
|
||||
|
||||
label->resize(10, h-30, w-20, 20);
|
||||
|
||||
Fl_Window::layout();
|
||||
}
|
||||
|
||||
static void timeout(void *data) {
|
||||
|
||||
if(!Fl::get_key_state(FL_Alt_L))
|
||||
{
|
||||
Frame *f = win->selected_frame();
|
||||
if(f) {
|
||||
f->activate();
|
||||
f->raise();
|
||||
}
|
||||
|
||||
win->destroy();
|
||||
delete win;
|
||||
win=0;
|
||||
|
||||
} else
|
||||
Fl::repeat_timeout(0.1, timeout, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void show_tabmenu(int direction)
|
||||
{
|
||||
if(!win)
|
||||
{
|
||||
Frame_List list;
|
||||
for(uint n=stack_order.size(); n--;) {
|
||||
Frame *f = stack_order[n];
|
||||
if( (f->state()==NORMAL || f->state()==ICONIC) && (f->desktop()==Desktop::current() || !f->desktop()) && !f->frame_flag(SKIP_LIST) && !f->frame_flag(SKIP_FOCUS) && !f->frame_flag(CLICK_TO_FOCUS) ) {
|
||||
list.append(f);
|
||||
}
|
||||
}
|
||||
if(list.count()<1) return;
|
||||
if(list.count()==1) {
|
||||
list[0]->activate();
|
||||
list[0]->raise();
|
||||
return;
|
||||
}
|
||||
|
||||
win = new TabWin(list, direction);
|
||||
|
||||
XSetWindowAttributes attr;
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = fl_colormap;
|
||||
attr.bit_gravity = 0;
|
||||
attr.event_mask = ExposureMask | StructureNotifyMask
|
||||
| KeyPressMask | KeyReleaseMask | KeymapStateMask | FocusChangeMask
|
||||
| ButtonPressMask | ButtonReleaseMask
|
||||
| EnterWindowMask | LeaveWindowMask
|
||||
| PointerMotionMask;
|
||||
attr.override_redirect = 1;
|
||||
attr.save_under = 0;
|
||||
|
||||
int mask = CWBorderPixel|CWColormap|CWEventMask|CWBitGravity|CWOverrideRedirect|CWSaveUnder;
|
||||
Window xid = XCreateWindow(fl_display,
|
||||
fl_xid(root),
|
||||
win->x(), win->y(), win->w(), win->h(),
|
||||
0, // borderwidth
|
||||
fl_visual->depth,
|
||||
InputOutput,
|
||||
fl_visual->visual,
|
||||
mask, &attr);
|
||||
|
||||
XDestroyWindow(fl_display, fl_xid(win));
|
||||
Fl_X::i(win)->xid = xid;
|
||||
|
||||
win->show();
|
||||
XMapWindow(fl_display, xid);
|
||||
|
||||
Fl::add_timeout(0.1, timeout, 0);
|
||||
}
|
||||
|
||||
win->next();
|
||||
}
|
||||
|
117
edewm/Theme.cpp
Normal file
117
edewm/Theme.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "Theme.h"
|
||||
#include <efltk/Fl.h>
|
||||
|
||||
namespace Theme {
|
||||
|
||||
Fl_Image *images[IMAGES_LAST];
|
||||
Fl_Color _frame_color;
|
||||
Fl_Image_List loaded;
|
||||
bool use;
|
||||
|
||||
bool use_theme() { return use; }
|
||||
void use_theme(bool val) { use = val; }
|
||||
|
||||
static Fl_Image *load_image(const char *name, const Fl_String &path, Fl_Config &cfg)
|
||||
{
|
||||
Fl_String filename;
|
||||
cfg.read(name, filename, 0);
|
||||
Fl_String img_path(path + filename);
|
||||
return Fl_Image::read(img_path);
|
||||
}
|
||||
|
||||
bool load_theme(const Fl_String &file)
|
||||
{
|
||||
if(!fl_file_exists(file))
|
||||
return false;
|
||||
|
||||
int pos = file.rpos('/');
|
||||
if(pos==-1) return false;
|
||||
|
||||
unload_theme();
|
||||
|
||||
Fl_String path(file.sub_str(0, pos+1));
|
||||
Fl_String filename;
|
||||
|
||||
Fl_Config themeconf(file);
|
||||
themeconf.set_section("Theme");
|
||||
|
||||
themeconf.read("Frame color", _frame_color, FL_NO_COLOR);
|
||||
|
||||
images[TITLEBAR_BG] = load_image("Title image", path, themeconf);
|
||||
if(images[TITLEBAR_BG])
|
||||
loaded.append(images[TITLEBAR_BG]);
|
||||
|
||||
Fl_Image *up = load_image("Close image up", path, themeconf);
|
||||
Fl_Image *down = load_image("Close image down", path, themeconf);
|
||||
if(up && down) {
|
||||
images[TITLEBAR_CLOSE_UP] = up;
|
||||
images[TITLEBAR_CLOSE_DOWN] = down;
|
||||
up->state_effect(false);
|
||||
down->state_effect(false);
|
||||
loaded.append(up);
|
||||
loaded.append(down);
|
||||
} else {
|
||||
if(up) delete up;
|
||||
if(down) delete down;
|
||||
}
|
||||
|
||||
up = load_image("Maximize image up", path, themeconf);
|
||||
down = load_image("Maximize image down", path, themeconf);
|
||||
if(up && down) {
|
||||
images[TITLEBAR_MAX_UP] = up;
|
||||
images[TITLEBAR_MAX_DOWN] = down;
|
||||
up->state_effect(false);
|
||||
down->state_effect(false);
|
||||
loaded.append(up);
|
||||
loaded.append(down);
|
||||
} else {
|
||||
if(up) delete up;
|
||||
if(down) delete down;
|
||||
}
|
||||
|
||||
up = load_image("Minimize image up", path, themeconf);
|
||||
down = load_image("Minimize image down", path, themeconf);
|
||||
if(up && down) {
|
||||
images[TITLEBAR_MIN_UP] = up;
|
||||
images[TITLEBAR_MIN_DOWN] = down;
|
||||
up->state_effect(false);
|
||||
down->state_effect(false);
|
||||
loaded.append(up);
|
||||
loaded.append(down);
|
||||
} else {
|
||||
if(up) delete up;
|
||||
if(down) delete down;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void unload_theme()
|
||||
{
|
||||
for(unsigned n=0; n<loaded.size(); n++) {
|
||||
delete loaded[n];
|
||||
}
|
||||
loaded.clear();
|
||||
|
||||
for(int n=0; n<IMAGES_LAST; n++)
|
||||
images[n] = 0;
|
||||
|
||||
_frame_color = FL_NO_COLOR;
|
||||
}
|
||||
|
||||
Fl_Image *image(int which)
|
||||
{
|
||||
if(which<0 || which>=IMAGES_LAST) {
|
||||
Fl::warning("Invalid theme image index: %d", which);
|
||||
return 0;
|
||||
}
|
||||
return images[which];
|
||||
}
|
||||
|
||||
Fl_Color frame_color()
|
||||
{
|
||||
return _frame_color;
|
||||
}
|
||||
|
||||
}; /* namespace Theme */
|
||||
|
31
edewm/Theme.h
Normal file
31
edewm/Theme.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _THEME_H_
|
||||
#define _THEME_H_
|
||||
|
||||
#include <efltk/Fl_Image.h>
|
||||
#include <efltk/Fl_Image_List.h>
|
||||
#include <efltk/Fl_Multi_Image.h>
|
||||
#include <efltk/Fl_Config.h>
|
||||
#include <efltk/Fl_String.h>
|
||||
|
||||
enum {
|
||||
TITLEBAR_BG = 0,
|
||||
TITLEBAR_CLOSE_UP, TITLEBAR_CLOSE_DOWN,
|
||||
TITLEBAR_MAX_UP, TITLEBAR_MAX_DOWN,
|
||||
TITLEBAR_MIN_UP, TITLEBAR_MIN_DOWN,
|
||||
IMAGES_LAST
|
||||
};
|
||||
|
||||
namespace Theme {
|
||||
|
||||
extern bool use_theme();
|
||||
extern void use_theme(bool val);
|
||||
|
||||
extern bool load_theme(const Fl_String &file);
|
||||
extern void unload_theme();
|
||||
|
||||
extern Fl_Image *image(int which);
|
||||
extern Fl_Color frame_color();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
657
edewm/Titlebar.cpp
Normal file
657
edewm/Titlebar.cpp
Normal file
@ -0,0 +1,657 @@
|
||||
#include "Titlebar.h"
|
||||
#include "Windowmanager.h"
|
||||
#include "Frame.h"
|
||||
#include "Desktop.h"
|
||||
#include "Icon.h"
|
||||
#include "Theme.h"
|
||||
|
||||
#include <efltk/Fl_Item.h>
|
||||
#include <efltk/Fl_Divider.h>
|
||||
#include <efltk/fl_draw.h>
|
||||
#include <efltk/Fl_Util.h>
|
||||
#include <efltk/Fl_Menu_.h>
|
||||
#include <efltk/Fl.h>
|
||||
#include <efltk/fl_ask.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
extern bool grab();
|
||||
extern void grab_cursor(bool grab);
|
||||
|
||||
int Titlebar::box_type = 0;
|
||||
int Titlebar::label_align = FL_ALIGN_LEFT;
|
||||
int Titlebar::default_height = 20;
|
||||
|
||||
//Fl_Config wm_config(fl_find_config_file("wmanager.conf", true));
|
||||
|
||||
static Fl_Menu_ *title_menu=0;
|
||||
Frame *menu_frame=0; //This is set to frame,where menu were popped up
|
||||
|
||||
// this is called when user clicks the buttons:
|
||||
void Frame::cb_button_close(Fl_Button* b)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void Frame::cb_button_kill(Fl_Button* b)
|
||||
{
|
||||
kill();
|
||||
}
|
||||
|
||||
/*
|
||||
static void animate(int fx, int fy, int fw, int fh,
|
||||
int tx, int ty, int tw, int th)
|
||||
{
|
||||
# undef max
|
||||
# define max(a,b) (a) > (b) ? (a) : (b)
|
||||
double max_steps = max( (tw-fw), (th-fh) );
|
||||
double min_steps = max( (fw-tw), (fh-th) );
|
||||
double steps = max(max_steps, min_steps);
|
||||
steps/=Frame::animate_speed;
|
||||
|
||||
double sx = max( ((double)(fx-tx)/steps), ((double)(tx-fx)/steps) );
|
||||
double sy = max( ((double)(fy-ty)/steps), ((double)(ty-fy)/steps) );
|
||||
double sw = max( ((double)(fw-tw)/steps), ((double)(tw-fw)/steps) );
|
||||
double sh = max( ((double)(fh-th)/steps), ((double)(th-fh)/steps) );
|
||||
|
||||
int xinc = fx < tx ? 1 : -1;
|
||||
int yinc = fy < ty ? 1 : -1;
|
||||
int winc = fw < tw ? 1 : -1;
|
||||
int hinc = fh < th ? 1 : -1;
|
||||
double rx=fx,ry=fy,rw=fw,rh=fh;
|
||||
|
||||
XGrabServer(fl_display);
|
||||
|
||||
while(steps-- > 0) {
|
||||
|
||||
rx+=(sx*xinc);
|
||||
ry+=(sy*yinc);
|
||||
rw+=(sw*winc);
|
||||
rh+=(sh*hinc);
|
||||
|
||||
draw_overlay((int)rx, (int)ry, (int)rw, (int)rh);
|
||||
|
||||
Fl::sleep(10);
|
||||
XFlush(fl_display);
|
||||
}
|
||||
|
||||
clear_overlay();
|
||||
|
||||
XUngrabServer(fl_display);
|
||||
}
|
||||
|
||||
void Frame::cb_button_max(Fl_Button* b)
|
||||
{
|
||||
if(maximized) {
|
||||
if(Frame::animate) {
|
||||
::animate(x(), y(), w(), h(),
|
||||
restore_x, restore_y, restore_w, restore_h);
|
||||
}
|
||||
|
||||
set_size(restore_x, restore_y, restore_w, restore_h);
|
||||
maximized = false;
|
||||
|
||||
} else {
|
||||
|
||||
bool m = true;
|
||||
|
||||
restore_x = x();
|
||||
restore_y = y();
|
||||
restore_w = w();
|
||||
restore_h = h();
|
||||
|
||||
int W=root->w(), H=root->h();
|
||||
W-=offset_w;
|
||||
H-=offset_h;
|
||||
if(ICCCM::get_size(this, W, H)) {
|
||||
m=false;
|
||||
}
|
||||
W+=offset_w;
|
||||
H+=offset_h;
|
||||
|
||||
if(Frame::animate) {
|
||||
::animate(x(), y(), w(), h(),
|
||||
root->x(), root->y(), root->w(), root->h());
|
||||
}
|
||||
|
||||
set_size(root->x(), root->y(), W, H);
|
||||
|
||||
maximized = m;
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void Frame::cb_button_max(Fl_Button* b)
|
||||
{
|
||||
if(maximized)
|
||||
restore();
|
||||
else
|
||||
maximize();
|
||||
}
|
||||
|
||||
void Frame::cb_button_min(Fl_Button* b)
|
||||
{
|
||||
iconize();
|
||||
}
|
||||
|
||||
// Min/Max/Close button symbols drawing stuff:
|
||||
extern int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable);
|
||||
|
||||
#define vv(x,y) fl_vertex(x,y)
|
||||
void draw_cl(Fl_Color col)
|
||||
{
|
||||
fl_rotate(45);
|
||||
fl_color(col);
|
||||
|
||||
vv(-0.9f,-0.12f); vv(-0.9f,0.12f); vv(0.9f,0.12f); vv(0.9f,-0.12f); fl_fill_stroke(FL_DARK3);
|
||||
vv(-0.12f,-0.9f); vv(-0.12f,0.9f); vv(0.12f,0.9f); vv(0.12f,-0.9f); fl_fill_stroke(FL_DARK3);
|
||||
}
|
||||
|
||||
#define MAX_OF .6f
|
||||
void draw_max(Fl_Color col)
|
||||
{
|
||||
fl_color(col);
|
||||
|
||||
vv(-MAX_OF, -MAX_OF); vv(MAX_OF, -MAX_OF);
|
||||
vv(MAX_OF,-MAX_OF+0.4); vv(-MAX_OF,-MAX_OF+0.4);
|
||||
fl_fill();
|
||||
|
||||
vv(MAX_OF,-MAX_OF); vv(MAX_OF,MAX_OF);
|
||||
vv(-MAX_OF,MAX_OF); vv(-MAX_OF,-MAX_OF);
|
||||
fl_stroke();
|
||||
}
|
||||
|
||||
#define MIN_OF .5f
|
||||
void draw_min(Fl_Color col)
|
||||
{
|
||||
fl_color(col);
|
||||
|
||||
vv(-MIN_OF, MIN_OF); vv(MIN_OF, MIN_OF);
|
||||
vv(MIN_OF, MIN_OF+.2f); vv(-MIN_OF, MIN_OF+.2f);
|
||||
fl_fill();
|
||||
}
|
||||
|
||||
// static callbacks for efltk:
|
||||
void button_cb_close(Fl_Widget *w, void *d)
|
||||
{
|
||||
Frame *f = d ? (Frame *)d : menu_frame;
|
||||
f->cb_button_close((Fl_Button*)w);
|
||||
}
|
||||
|
||||
void button_cb_kill(Fl_Widget *w, void *d)
|
||||
{
|
||||
Frame *f = d ? (Frame *)d : menu_frame;
|
||||
f->cb_button_kill((Fl_Button*)w);
|
||||
}
|
||||
|
||||
void button_cb_max(Fl_Widget *w, void *d)
|
||||
{
|
||||
Frame *f = d ? (Frame *)d : menu_frame;
|
||||
f->cb_button_max((Fl_Button*)w);
|
||||
}
|
||||
|
||||
void button_cb_min(Fl_Widget *w, void *d)
|
||||
{
|
||||
Frame *f = d ? (Frame *)d : menu_frame;
|
||||
f->cb_button_min((Fl_Button*)w);
|
||||
}
|
||||
|
||||
void Titlebar::cb_change_desktop(Fl_Widget *w, void *data)
|
||||
{
|
||||
Desktop *d = (Desktop*)data;
|
||||
menu_frame->desktop_ = d;
|
||||
|
||||
if(d && d!=Desktop::current()) {
|
||||
Desktop::current(d);
|
||||
menu_frame->raise();
|
||||
}
|
||||
|
||||
menu_frame->send_desktop();
|
||||
menu_frame=0;
|
||||
}
|
||||
|
||||
void update_desktops(Fl_Group *g)
|
||||
{
|
||||
g->clear();
|
||||
g->begin();
|
||||
|
||||
Fl_Item *i;
|
||||
|
||||
i = new Fl_Item(_("Sticky"));
|
||||
i->type(Fl_Item::TOGGLE);
|
||||
i->callback(Titlebar::cb_change_desktop);
|
||||
if(menu_frame->desktop()) {
|
||||
i->clear_value();
|
||||
i->user_data(0);
|
||||
} else {
|
||||
i->set_value();
|
||||
i->user_data(Desktop::current());
|
||||
}
|
||||
|
||||
|
||||
new Fl_Divider();
|
||||
|
||||
for(uint n=0; n<desktops.size(); n++) {
|
||||
Desktop *d = desktops[n];
|
||||
i = new Fl_Item(d->name());
|
||||
i->type(Fl_Item::RADIO);
|
||||
|
||||
if(menu_frame->desktop()==d) i->set_value();
|
||||
else i->clear_value();
|
||||
|
||||
i->callback(Titlebar::cb_change_desktop, d);
|
||||
}
|
||||
|
||||
g->end();
|
||||
}
|
||||
|
||||
#include "WMWindow.h"
|
||||
#include <efltk/Fl_Box.h>
|
||||
#include <efltk/Fl_Divider.h>
|
||||
#include <efltk/Fl_Value_Input.h>
|
||||
#include <efltk/fl_ask.h>
|
||||
|
||||
Fl_Button *ok_button;
|
||||
Fl_Value_Input *w_width, *w_height;
|
||||
//Fl_Input *size;
|
||||
static WMWindow *win = 0;
|
||||
|
||||
static void real_set_size_cb(Fl_Widget *w, void *d)
|
||||
{
|
||||
Frame *f = (Frame*)d;
|
||||
|
||||
int W = (int)w_width->value();
|
||||
int H = (int)w_height->value();
|
||||
ICCCM::get_size(f, W, H);
|
||||
|
||||
f->set_size(f->x(), f->y(), W, H);
|
||||
f->redraw();
|
||||
|
||||
win->destroy();
|
||||
}
|
||||
|
||||
static void close_set_size_cb(Fl_Widget *w, void *d)
|
||||
{
|
||||
win->destroy();
|
||||
}
|
||||
|
||||
static void set_size_cb(Fl_Widget *w, void *d)
|
||||
{
|
||||
win = new WMWindow(300, 110, _("Set size"));
|
||||
Fl_Box *b = new Fl_Box(5, 5, 295, 15, _("Set size to window:"));
|
||||
b->label_font(b->label_font()->bold());
|
||||
|
||||
Fl_String tmplabel = menu_frame->label();
|
||||
if (tmplabel.length() > 50)
|
||||
tmplabel = tmplabel.sub_str(0,20) + " ... " + tmplabel.sub_str(tmplabel.length()-20,20);
|
||||
|
||||
b = new Fl_Box(0, 20, 296, 15, tmplabel);
|
||||
|
||||
w_width = new Fl_Value_Input(45, 45, 90, 20, _("width:"));
|
||||
w_width->step(1);
|
||||
w_height = new Fl_Value_Input(195, 45, 90, 20, _("height:"));
|
||||
w_height->step(1);
|
||||
new Fl_Divider(5, 70, 290, 10);
|
||||
|
||||
Fl_Button *but = ok_button = new Fl_Button(60,80,85,25, _("&OK"));
|
||||
but->callback(real_set_size_cb);
|
||||
|
||||
but = new Fl_Button(155, 80, 85, 25, _("&Cancel"));
|
||||
but->callback(close_set_size_cb);
|
||||
|
||||
win->end();
|
||||
|
||||
w_width->value(menu_frame->w());
|
||||
w_height->value(menu_frame->h());
|
||||
ok_button->user_data(menu_frame);
|
||||
|
||||
win->callback(close_set_size_cb);
|
||||
win->show();
|
||||
}
|
||||
|
||||
void Titlebar::popup_menu(Frame *frame)
|
||||
{
|
||||
menu_frame = frame;
|
||||
|
||||
static Fl_Widget *max;
|
||||
static Fl_Widget *set_size;
|
||||
static Fl_Widget *min;
|
||||
static Fl_Group *desktop;
|
||||
|
||||
if(!title_menu) {
|
||||
title_menu = new Fl_Menu_();
|
||||
max=title_menu->add(_("Maximize"), 0, button_cb_max);
|
||||
min=title_menu->add(_("Minimize"), 0, button_cb_min);
|
||||
set_size=title_menu->add(_("Set size"), 0, set_size_cb, 0, FL_MENU_DIVIDER);
|
||||
desktop=(Fl_Group*)title_menu->add(_("To Desktop"), 0, 0, 0, FL_SUBMENU|FL_MENU_DIVIDER);
|
||||
title_menu->add(_("Kill"), 0, button_cb_kill);
|
||||
title_menu->add(_("Close"), 0, button_cb_close);
|
||||
title_menu->end();
|
||||
|
||||
}
|
||||
|
||||
update_desktops(desktop);
|
||||
|
||||
if(menu_frame->maximized) max->label(_("Restore"));
|
||||
else max->label(_("Maximize"));
|
||||
|
||||
|
||||
// we don't want animation for dialogs and utils frames
|
||||
// MWM hints can set MAXIMIZE and MINIMIZE options separately
|
||||
// so we must check them each
|
||||
if(menu_frame->window_type() == TYPE_NORMAL)
|
||||
{
|
||||
if(menu_frame->decor_flag(MAXIMIZE))
|
||||
{
|
||||
max->activate();
|
||||
set_size->activate();
|
||||
}
|
||||
if(menu_frame->decor_flag(MINIMIZE))
|
||||
min->activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
max->deactivate();
|
||||
set_size->deactivate();
|
||||
min->deactivate();
|
||||
}
|
||||
|
||||
title_menu->Fl_Group::focus(-1);
|
||||
title_menu->popup(Fl::event_x_root(), Fl::event_y_root());
|
||||
|
||||
menu_frame = 0;
|
||||
}
|
||||
|
||||
Titlebar_Button::Titlebar_Button(int type)
|
||||
: Fl_Button(0,0,0,0), m_type(type)
|
||||
{
|
||||
focus_box(FL_NO_BOX);
|
||||
label_type(FL_SYMBOL_LABEL);
|
||||
|
||||
switch(m_type) {
|
||||
case TITLEBAR_MAX_UP: label("@mx"); break;
|
||||
case TITLEBAR_MIN_UP: label("@ii"); break;
|
||||
case TITLEBAR_CLOSE_UP: label("@xx"); break;
|
||||
};
|
||||
}
|
||||
|
||||
void Titlebar_Button::draw()
|
||||
{
|
||||
int idx = m_type;
|
||||
if(flags() & FL_VALUE) idx++;
|
||||
|
||||
Fl_Image *i = Theme::image(idx);
|
||||
if(i) {
|
||||
Fl_Flags scale = 0;
|
||||
if(i->height()!=h()) scale = FL_ALIGN_SCALE;
|
||||
i->draw(0,0,w(),h(), scale);
|
||||
} else {
|
||||
Fl_Button::draw();
|
||||
}
|
||||
}
|
||||
|
||||
Titlebar::Titlebar(int x,int y,int w,int h,const char *l)
|
||||
: Fl_Window(x,y,w,h,0),
|
||||
_close(TITLEBAR_CLOSE_UP), _max(TITLEBAR_MAX_UP), _min(TITLEBAR_MIN_UP)
|
||||
{
|
||||
f = (Frame *)parent();
|
||||
title_icon = 0;
|
||||
text_w=0;
|
||||
|
||||
static bool init = false;
|
||||
if(!init) {
|
||||
fl_add_symbol("xx", draw_cl, 1);
|
||||
fl_add_symbol("mx", draw_max, 1);
|
||||
fl_add_symbol("ii", draw_min, 1);
|
||||
init = true;
|
||||
}
|
||||
|
||||
setting_changed();
|
||||
end();
|
||||
}
|
||||
|
||||
Titlebar::~Titlebar()
|
||||
{
|
||||
}
|
||||
|
||||
void Titlebar::setting_changed()
|
||||
{
|
||||
_close.callback(button_cb_close, f);
|
||||
_max.callback(button_cb_max, f);
|
||||
_min.callback(button_cb_min, f);
|
||||
|
||||
if(Titlebar::default_height != h()) {
|
||||
h(Titlebar::default_height);
|
||||
f->updateBorder();
|
||||
}
|
||||
|
||||
layout();
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Titlebar::show()
|
||||
{
|
||||
if(!shown()) create();
|
||||
|
||||
XMapWindow(fl_display, fl_xid(this));
|
||||
XRaiseWindow(fl_display, fl_xid(this));
|
||||
}
|
||||
|
||||
void Titlebar::hide()
|
||||
{
|
||||
if(shown())
|
||||
XUnmapWindow(fl_display, fl_xid(this));
|
||||
}
|
||||
|
||||
#define set_box(b) if(box()!=b) box(b); break
|
||||
|
||||
void Titlebar::layout()
|
||||
{
|
||||
if(Theme::use_theme()) {
|
||||
if(box()!=FL_FLAT_BOX) box(FL_FLAT_BOX);
|
||||
} else {
|
||||
switch(box_type) {
|
||||
default:
|
||||
case 0: set_box(FL_FLAT_BOX);
|
||||
case 1: set_box(FL_HOR_SHADE_FLAT_BOX);
|
||||
case 2: set_box(FL_THIN_DOWN_BOX);
|
||||
case 3: set_box(FL_UP_BOX);
|
||||
case 4: set_box(FL_DOWN_BOX);
|
||||
case 5: set_box(FL_PLASTIC_BOX);
|
||||
}
|
||||
}
|
||||
|
||||
int W = w()-box()->dx();
|
||||
|
||||
int lsize = h()/2+2;
|
||||
label_size(lsize);
|
||||
|
||||
// Try to detect what buttons are showed
|
||||
if(!f->func_flag(MINIMIZE)) _min.deactivate(); else _min.activate();
|
||||
if(!f->func_flag(MAXIMIZE)) _max.deactivate(); else _max.activate();
|
||||
|
||||
if(!f->decor_flag(MINIMIZE) || f->frame_flag(KEEP_ASPECT)) _min.hide();
|
||||
if(!f->decor_flag(MAXIMIZE) || f->frame_flag(KEEP_ASPECT)) _max.hide();
|
||||
|
||||
if(f->size_hints->min_width==f->size_hints->max_width || f->transient_for_xid) {
|
||||
_min.hide();
|
||||
_max.hide();
|
||||
} else {
|
||||
_min.show();
|
||||
_max.show();
|
||||
}
|
||||
|
||||
int offset=0;
|
||||
int s = h();
|
||||
int mid = 0;
|
||||
if(!Theme::use_theme()) {
|
||||
s -= 4;
|
||||
mid = 2;
|
||||
offset=2;
|
||||
}
|
||||
int bx = W-s-offset;
|
||||
|
||||
_close.resize(bx, mid, s, s);
|
||||
if(_close.visible()) bx -= s+offset;
|
||||
|
||||
_max.resize(bx, mid, s, s);
|
||||
if(_max.visible()) bx -= s+offset;
|
||||
|
||||
_min.resize(bx, mid, s, s);
|
||||
|
||||
text_w = bx - (f->decor_flag(SYSMENU)?h():0) - 10;
|
||||
|
||||
fl_font(label_font(), label_size());
|
||||
if(!f->label().empty()) {
|
||||
Fl_Widget::label(fl_cut_line(f->label(), text_w));
|
||||
if(strcmp(label(), f->label())) {
|
||||
tooltip(f->label());
|
||||
} else {
|
||||
tooltip("");
|
||||
}
|
||||
} else {
|
||||
label("");
|
||||
tooltip("");
|
||||
}
|
||||
|
||||
// Reset layout flags
|
||||
Fl_Widget::layout();
|
||||
}
|
||||
|
||||
void Titlebar::draw()
|
||||
{
|
||||
DBG("Titlebar::draw(): %s", label().c_str());
|
||||
|
||||
if(Theme::use_theme() && Theme::image(TITLEBAR_BG)) {
|
||||
int X=0, Y=0, W=w(), H=h();
|
||||
Theme::image(TITLEBAR_BG)->draw(X,Y,W,H,FL_ALIGN_SCALE);
|
||||
} else {
|
||||
draw_box();
|
||||
}
|
||||
|
||||
int s=h()-4;
|
||||
|
||||
// Resize and set image & mask
|
||||
if(f->icon() && f->decor_flag(SYSMENU)) {
|
||||
title_icon = f->icon()->get_icon(s, s);
|
||||
} else
|
||||
title_icon = 0;
|
||||
|
||||
int tx = box()->dx()+1;
|
||||
|
||||
if(title_icon) {
|
||||
title_icon->draw(2,2, s, s);
|
||||
tx += s + 5; // Separate text a few pixels from icon
|
||||
}
|
||||
|
||||
draw_label(tx, 0, text_w, h(), Titlebar::label_align);
|
||||
|
||||
draw_child(_close);
|
||||
draw_child(_max);
|
||||
draw_child(_min);
|
||||
}
|
||||
|
||||
|
||||
int Titlebar::handle(int event)
|
||||
{
|
||||
static bool grabbed=false;
|
||||
static int dx,dy,nx,ny;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case FL_PUSH: {
|
||||
if(grabbed) return 1;
|
||||
|
||||
dx = Fl::event_x_root()-f->x();
|
||||
dy = Fl::event_y_root()-f->y();
|
||||
nx = Fl::event_x_root()-dx;
|
||||
ny = Fl::event_y_root()-dy;
|
||||
|
||||
// Send event to buttons...
|
||||
for(int i = children(); i--;) {
|
||||
Fl_Widget& o = *child(i);
|
||||
int mx = Fl::event_x() - o.x() - 2;
|
||||
int my = Fl::event_y() - o.y() - 2;
|
||||
if (mx >= 0 && mx < o.w() && my >= 0 && my < o.h()+4)
|
||||
if(child(i)->send(event)) {
|
||||
extern bool handle_title;
|
||||
handle_title = false;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(Fl::event_clicks() && Fl::event_button()==1) {
|
||||
// we don't want animation for dialogs and utils frames
|
||||
if(f->window_type() == TYPE_NORMAL && f->decor_flag(MAXIMIZE))
|
||||
f->cb_button_max(0);
|
||||
|
||||
Fl::event_clicks(0);
|
||||
return 1;
|
||||
} else if (Fl::event_button()==3) {
|
||||
Titlebar::popup_menu(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
case FL_RELEASE: {
|
||||
if(Fl::event_state(FL_BUTTON1)) return 1;
|
||||
|
||||
if(grabbed) {
|
||||
if(!Frame::do_opaque) {
|
||||
clear_overlay();
|
||||
f->set_size(nx, ny, f->w(), f->h());
|
||||
XUngrabServer(fl_display);
|
||||
}
|
||||
grab_cursor(false);
|
||||
grabbed = false;
|
||||
}
|
||||
|
||||
if(root->get_cursor()==FL_CURSOR_MOVE)
|
||||
root->set_default_cursor();
|
||||
|
||||
if (Fl::event_is_click()) {
|
||||
f->activate();
|
||||
f->raise();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
case FL_DRAG: {
|
||||
if(Fl::event_is_click()) return 1; // don't drag yet
|
||||
if(!Fl::event_state(FL_BUTTON1)) return 0;
|
||||
|
||||
// Change to MOVE cursor
|
||||
if(root->get_cursor()!=FL_CURSOR_MOVE) {
|
||||
root->set_cursor(FL_CURSOR_MOVE, FL_WHITE, FL_BLACK);
|
||||
}
|
||||
|
||||
// We need to grab server while moving,
|
||||
// since if underlying window redraws our overlay will fuck up...
|
||||
if(!grabbed) {
|
||||
if(!Frame::do_opaque) XGrabServer(fl_display);
|
||||
grab_cursor(true);
|
||||
grabbed=true;
|
||||
}
|
||||
|
||||
nx = Fl::event_x_root()-dx;
|
||||
ny = Fl::event_y_root()-dy;
|
||||
f->handle_move(nx, ny);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// default:
|
||||
// return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
59
edewm/Titlebar.h
Normal file
59
edewm/Titlebar.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef _TITLEBAR_H_
|
||||
#define _TITLEBAR_H_
|
||||
|
||||
class Frame;
|
||||
#include <efltk/Fl_Button.h>
|
||||
#include <efltk/Fl_Window.h>
|
||||
#include <efltk/Fl_Multi_Image.h>
|
||||
#include <efltk/Fl_Double_Window.h>
|
||||
#include <efltk/Fl_Group.h>
|
||||
#include <efltk/x.h>
|
||||
|
||||
#include <efltk/Fl_Image.h>
|
||||
|
||||
class Titlebar_Button : public Fl_Button
|
||||
{
|
||||
int m_type;
|
||||
public:
|
||||
Titlebar_Button(int type);
|
||||
void draw();
|
||||
};
|
||||
|
||||
class Titlebar : public Fl_Window {
|
||||
friend class Frame;
|
||||
public:
|
||||
Titlebar(int x,int y,int w,int h,const char *l=0);
|
||||
virtual ~Titlebar();
|
||||
|
||||
void setting_changed();
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
virtual void draw();
|
||||
virtual int handle(int event);
|
||||
virtual void layout();
|
||||
|
||||
void draw_opaque(int, int, int, int);
|
||||
|
||||
Fl_Button *close() { return &_close; }
|
||||
Fl_Button *min() { return &_min; }
|
||||
Fl_Button *max() { return &_max; }
|
||||
|
||||
static void popup_menu(Frame *frame);
|
||||
static void cb_change_desktop(Fl_Widget *w, void *data);
|
||||
|
||||
static int box_type;
|
||||
static int label_align;
|
||||
static int default_height;
|
||||
|
||||
Frame *f;
|
||||
protected:
|
||||
Fl_Image *title_icon;
|
||||
|
||||
Titlebar_Button _close, _max, _min;
|
||||
int text_w;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
43
edewm/WMWindow.cpp
Normal file
43
edewm/WMWindow.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
// X does not echo back the window-map events (it probably should when
|
||||
// override_redirect is off). Unfortunately this means you have to use
|
||||
// this subclass if you want a "normal" fltk window, it will force a
|
||||
// Frame to be created and destroy it upon hide.
|
||||
|
||||
// Warning: modal() does not work! Don't turn it on as it screws up the
|
||||
// interface with the window borders. You can use set_non_modal() to
|
||||
// disable the iconize box but the window manager must be written to
|
||||
// not be modal.
|
||||
|
||||
#include <efltk/Fl.h>
|
||||
#include "WMWindow.h"
|
||||
#include "Frame.h"
|
||||
#include "Windowmanager.h"
|
||||
|
||||
extern int dont_set_event_mask;
|
||||
|
||||
void WMWindow::create()
|
||||
{
|
||||
Fl_Window::create();
|
||||
if(!frame) {
|
||||
dont_set_event_mask = 1;
|
||||
frame = new Frame(fl_xid(this));
|
||||
dont_set_event_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WMWindow::destroy()
|
||||
{
|
||||
if(frame) {
|
||||
frame->destroy_frame();
|
||||
frame=0;
|
||||
}
|
||||
Fl_Window::destroy();
|
||||
}
|
||||
|
||||
int WMWindow::handle(int e)
|
||||
{
|
||||
if(e==FL_PUSH || e==FL_MOUSEWHEEL) {
|
||||
frame->content_click();
|
||||
}
|
||||
return Fl_Window::handle(e);
|
||||
}
|
30
edewm/WMWindow.h
Normal file
30
edewm/WMWindow.h
Normal file
@ -0,0 +1,30 @@
|
||||
// X does not echo back the window-map events (it probably should when
|
||||
// override_redirect is off). Unfortunately this means you have to use
|
||||
// this subclass if you want a "normal" fltk window, it will force a
|
||||
// Frame to be created and destroy it upon hide.
|
||||
|
||||
// Warning: modal() does not work! Don't turn it on as it screws up the
|
||||
// interface with the window borders. You can use set_non_modal() to
|
||||
// disable the iconize box but the window manager must be written to
|
||||
// not be modal.
|
||||
|
||||
#ifndef _WMWINDOW_H_
|
||||
#define _WMWINDOW_H_
|
||||
|
||||
#include <efltk/Fl_Window.h>
|
||||
|
||||
class Frame;
|
||||
|
||||
class WMWindow : public Fl_Window {
|
||||
Frame* frame;
|
||||
static void cb(Fl_Widget *w, void *) { ((Fl_Window*)w)->destroy(); }
|
||||
public:
|
||||
WMWindow(int W, int H, const char* L = 0) : Fl_Window(W,H,L) { frame=0; callback(cb); }
|
||||
|
||||
virtual void create();
|
||||
virtual void destroy();
|
||||
|
||||
virtual int handle(int e);
|
||||
};
|
||||
|
||||
#endif
|
618
edewm/Windowmanager.cpp
Normal file
618
edewm/Windowmanager.cpp
Normal file
@ -0,0 +1,618 @@
|
||||
#include "Windowmanager.h"
|
||||
#include "Icccm.h"
|
||||
#include "Frame.h"
|
||||
#include "Desktop.h"
|
||||
#include "Winhints.h"
|
||||
#include "Theme.h"
|
||||
|
||||
#include <X11/Xproto.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../exset/exset.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
WindowManager *root;
|
||||
Window root_win;
|
||||
|
||||
Frame_List remove_list;
|
||||
|
||||
Frame_List stack_order;
|
||||
Frame_List map_order;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
static int initializing;
|
||||
Exset xset;
|
||||
|
||||
static const char* program_name;
|
||||
|
||||
// in Hotkeys.cpp
|
||||
extern int Handle_Hotkey();
|
||||
extern void Grab_Hotkeys();
|
||||
extern void read_hotkeys_configuration();
|
||||
void read_disp_configuration();
|
||||
|
||||
#if DESKTOPS
|
||||
extern void init_desktops();
|
||||
#endif
|
||||
|
||||
static const char* cfg, *cbg;
|
||||
|
||||
Fl_Color title_active_color, title_active_color_text;
|
||||
Fl_Color title_normal_color, title_normal_color_text;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// fltk calls this for any events it does not understand:
|
||||
static int wm_event_handler(int e)
|
||||
{
|
||||
if(fl_xevent.type == KeyPress) e=FL_KEY;
|
||||
|
||||
// XEvent that fltk did not understand.
|
||||
if(!e) {
|
||||
Window window = fl_xevent.xany.window;
|
||||
|
||||
// unfortunately most of the redirect events put the interesting
|
||||
// window id in a different place:
|
||||
switch (fl_xevent.type) {
|
||||
case CirculateNotify:
|
||||
case CirculateRequest:
|
||||
case ConfigureNotify:
|
||||
case ConfigureRequest:
|
||||
case CreateNotify:
|
||||
case GravityNotify:
|
||||
case MapNotify:
|
||||
case MapRequest:
|
||||
case ReparentNotify:
|
||||
case UnmapNotify:
|
||||
window = fl_xevent.xmaprequest.window;
|
||||
break;
|
||||
}
|
||||
|
||||
for(uint n=stack_order.size(); n--;) {
|
||||
Frame *c = stack_order[n];
|
||||
if (c->window() == window || fl_xid(c) == window) {
|
||||
return c->handle(&fl_xevent);
|
||||
}
|
||||
}
|
||||
|
||||
return root->handle(&fl_xevent);
|
||||
} else
|
||||
return root->handle(e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xerror_handler(Display* d, XErrorEvent* e) {
|
||||
if(initializing && (e->request_code == X_ChangeWindowAttributes) && e->error_code == BadAccess)
|
||||
Fl::fatal(_("Another window manager is running. You must exit it before running %s."), program_name);
|
||||
|
||||
#ifndef DEBUG
|
||||
if (e->error_code == BadWindow) return 0;
|
||||
if (e->error_code == BadColor) return 0;
|
||||
#endif
|
||||
|
||||
char buf1[128], buf2[128];
|
||||
sprintf(buf1, "XRequest.%d", e->request_code);
|
||||
XGetErrorDatabaseText(d,"",buf1,buf1,buf2,128);
|
||||
XGetErrorText(d, e->error_code, buf1, 128);
|
||||
Fl::warning("%s: %s: %s 0x%lx", program_name, buf2, buf1, e->resourceid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WindowManager::WindowManager(int argc, char *argv[])
|
||||
: Fl_Window(0, 0, Fl::w(), Fl::h())
|
||||
{
|
||||
root = this;
|
||||
xset = new Exset();
|
||||
init_wm(argc, argv);
|
||||
|
||||
box(FL_NO_BOX);
|
||||
}
|
||||
|
||||
// consume a switch from argv. Returns number of words eaten, 0 on error:
|
||||
int arg(int argc, char **argv, int &i) {
|
||||
const char *s = argv[i];
|
||||
if (s[0] != '-') return 0;
|
||||
s++;
|
||||
|
||||
// do single-word switches:
|
||||
if (!strcmp(s,"x")) {
|
||||
//exit_flag = 1;
|
||||
i++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// do switches with a value:
|
||||
const char *v = argv[i+1];
|
||||
if (i >= argc-1 || !v)
|
||||
return 0; // all the rest need an argument, so if missing it is an error
|
||||
|
||||
if (!strcmp(s, "cfg")) {
|
||||
cfg = v;
|
||||
} else if (!strcmp(s, "cbg")) {
|
||||
cbg = v;
|
||||
} else if (*s == 'v') {
|
||||
int visid = atoi(v);
|
||||
fl_open_display();
|
||||
XVisualInfo templt; int num;
|
||||
templt.visualid = visid;
|
||||
fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
|
||||
if (!fl_visual) Fl::fatal("No visual with id %d",visid);
|
||||
fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
|
||||
fl_visual->visual, AllocNone);
|
||||
} else
|
||||
return 0; // unrecognized
|
||||
// return the fact that we consumed 2 switches:
|
||||
i += 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
int real_align(int i) {
|
||||
switch(i) {
|
||||
default:
|
||||
case 0: break;
|
||||
case 1: return FL_ALIGN_RIGHT;
|
||||
case 2: return FL_ALIGN_CENTER;
|
||||
}
|
||||
return FL_ALIGN_LEFT;
|
||||
}
|
||||
|
||||
void read_configuration()
|
||||
{
|
||||
Fl_String buf;
|
||||
|
||||
Fl_Config wmconf(fl_find_config_file("wmanager.conf", 0));
|
||||
|
||||
wmconf.set_section("TitleBar");
|
||||
|
||||
wmconf.read("Active color", title_active_color, fl_rgb(0,0,128));
|
||||
wmconf.read("Normal color", title_normal_color, fl_rgb(192,192,192));
|
||||
|
||||
wmconf.read("Active color text", title_active_color_text, fl_rgb(255,255,255));
|
||||
wmconf.read("Normal color text", title_normal_color_text, fl_rgb(0,0,128));
|
||||
|
||||
wmconf.read("Box type", Titlebar::box_type, 0);
|
||||
wmconf.read("Height", Titlebar::default_height, 20);
|
||||
wmconf.read("Text align", Titlebar::label_align, 0);
|
||||
Titlebar::label_align = real_align(Titlebar::label_align);
|
||||
|
||||
wmconf.set_section("Resize");
|
||||
wmconf.read("Opaque resize", Frame::do_opaque, false);
|
||||
wmconf.read("Animate", Frame::animate, true);
|
||||
wmconf.read("Animate Speed", Frame::animate_speed, 15);
|
||||
|
||||
wmconf.set_section("Misc");
|
||||
wmconf.read("FocusFollowsMouse", Frame::focus_follows_mouse, false);
|
||||
|
||||
bool theme = false;
|
||||
wmconf.read("Use theme", theme, false);
|
||||
if(theme) {
|
||||
wmconf.read("Theme path", buf, 0);
|
||||
Theme::load_theme(buf);
|
||||
Theme::use_theme(true);
|
||||
} else {
|
||||
Theme::unload_theme();
|
||||
Theme::use_theme(false);
|
||||
}
|
||||
Frame::settings_changed_all();
|
||||
|
||||
read_hotkeys_configuration();
|
||||
}
|
||||
|
||||
void do_xset_from_conf()
|
||||
{
|
||||
Fl_Config config(fl_find_config_file("ede.conf",1));
|
||||
|
||||
int val1, val2, val3;
|
||||
|
||||
config.set_section("Mouse");
|
||||
config.read("Accel", val1, 4);
|
||||
config.read("Thress",val2, 4);
|
||||
xset.set_mouse(val1, val2);
|
||||
|
||||
config.set_section("Bell");
|
||||
config.read("Volume", val1, 50);
|
||||
config.read("Pitch", val2, 440);
|
||||
config.read("Duration", val3, 200);
|
||||
xset.set_bell(val1, val2, val3);
|
||||
|
||||
config.set_section("Keyboard");
|
||||
config.read("Repeat", val1, 1);
|
||||
config.read("ClickVolume", val2, 50);
|
||||
xset.set_keybd(val1, val2);
|
||||
|
||||
config.set_section("Screen");
|
||||
config.read("Delay", val1, 15);
|
||||
config.read("Pattern",val2, 2);
|
||||
xset.set_pattern(val1, val2);
|
||||
|
||||
config.read("CheckBlank", val1, 1);
|
||||
xset.set_check_blank(val1);
|
||||
|
||||
config.read("Pattern", val1, 2);
|
||||
xset.set_blank(val1);
|
||||
}
|
||||
|
||||
void WindowManager::init_wm(int argc, char *argv[])
|
||||
{
|
||||
static bool wm_inited = false;
|
||||
if(wm_inited) return;
|
||||
|
||||
DBG("init windowmanager");
|
||||
|
||||
fl_open_display();
|
||||
|
||||
XShapeQueryExtension(fl_display, &XShapeEventBase, &XShapeErrorBase);
|
||||
|
||||
wm_area.set(0, 0/*22*/, Fl::w(), Fl::h()/*-22*/);
|
||||
|
||||
program_name = fl_file_filename(argv[0]);
|
||||
int i;
|
||||
if(Fl::args(argc, argv, i, arg) < argc)
|
||||
Fl::error("options are:\n"
|
||||
" -d[isplay] host:#.#\tX display & screen to use\n"
|
||||
" -v[isual] #\t\tvisual to use\n"
|
||||
" -g[eometry] WxH+X+Y\tlimits windows to this area\n"
|
||||
" -x\t\t\tmenu says Exit instead of logout\n"
|
||||
" -bg color\t\tFrame color\n"
|
||||
" -fg color\t\tLabel color\n"
|
||||
" -bg2 color\t\tText field color\n"
|
||||
" -cfg color\t\tCursor color\n"
|
||||
" -cbg color\t\tCursor outline color" );
|
||||
|
||||
// Init started
|
||||
initializing = 1;
|
||||
|
||||
XSetErrorHandler(xerror_handler);
|
||||
Fl::add_handler(wm_event_handler);
|
||||
|
||||
init_atoms(); // intern atoms
|
||||
|
||||
read_configuration();
|
||||
do_xset_from_conf();
|
||||
|
||||
show(); // Set XID now
|
||||
|
||||
set_default_cursor();
|
||||
|
||||
ICCCM::set_iconsizes();
|
||||
MWM::set_motif_info();
|
||||
|
||||
register_protocols(fl_xid(this));
|
||||
|
||||
Grab_Hotkeys();
|
||||
|
||||
XSync(fl_display, 0);
|
||||
|
||||
init_desktops();
|
||||
|
||||
//Init done
|
||||
initializing = 0;
|
||||
wm_inited = true;
|
||||
|
||||
// find all the windows and create a Frame for each:
|
||||
Frame *f=0;
|
||||
unsigned int n;
|
||||
Window w1, w2, *wins;
|
||||
XWindowAttributes attr;
|
||||
XQueryTree(fl_display, fl_xid(this), &w1, &w2, &wins, &n);
|
||||
for (i = 0; i < (int)n; ++i) {
|
||||
XGetWindowAttributes(fl_display, wins[i], &attr);
|
||||
if(attr.override_redirect) continue;
|
||||
if(!attr.map_state) {
|
||||
if(getIntProperty(wins[i], _XA_WM_STATE, _XA_WM_STATE, 0) != IconicState)
|
||||
continue;
|
||||
}
|
||||
f = new Frame(wins[i], &attr);
|
||||
}
|
||||
XFree((void *)wins);
|
||||
|
||||
// Activate last one
|
||||
for(uint n=0; n<map_order.size(); n++) {
|
||||
Frame *f = map_order[n];
|
||||
if(f->desktop()==Desktop::current()) {
|
||||
f->activate();
|
||||
f->raise();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update_workarea(true);
|
||||
}
|
||||
|
||||
|
||||
void WindowManager::show()
|
||||
{
|
||||
if(!shown()) {
|
||||
create();
|
||||
|
||||
// Destroy FLTK window
|
||||
XDestroyWindow(fl_display, Fl_X::i(this)->xid);
|
||||
// Set RootWindow to our xid
|
||||
Fl_X::i(this)->xid = RootWindow(fl_display, fl_screen);
|
||||
root_win = RootWindow(fl_display, fl_screen);
|
||||
|
||||
// setting attributes on root window makes it the window manager:
|
||||
XSelectInput(fl_display, fl_xid(this),
|
||||
SubstructureRedirectMask | SubstructureNotifyMask |
|
||||
ColormapChangeMask | PropertyChangeMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
KeyPressMask | KeyReleaseMask | KeymapStateMask);
|
||||
|
||||
DBG("RootWindow ID set to xid");
|
||||
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::draw()
|
||||
{
|
||||
DBG("ROOT DRAW");
|
||||
//Redraw root window
|
||||
XClearWindow(fl_display, fl_xid(this));
|
||||
}
|
||||
|
||||
extern void set_frame_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg, Window wid);
|
||||
void WindowManager::set_default_cursor()
|
||||
{
|
||||
cursor = FL_CURSOR_ARROW;
|
||||
set_frame_cursor(FL_CURSOR_ARROW, FL_WHITE, FL_BLACK, root_win);
|
||||
}
|
||||
|
||||
void WindowManager::set_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg)
|
||||
{
|
||||
cursor = c;
|
||||
set_frame_cursor(c, bg, fg, root_win);
|
||||
}
|
||||
|
||||
Frame *WindowManager::find_by_wid(Window wid)
|
||||
{
|
||||
for(uint n=0; n<map_order.size(); n++) {
|
||||
Frame *f = map_order[n];
|
||||
if(f->window()==wid) return f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WindowManager::restack_windows()
|
||||
{
|
||||
Window *windows = new Window[1];
|
||||
int total=0;
|
||||
|
||||
DBG("Restack: DOCK, SPLASH");
|
||||
for(uint n=0; n<stack_order.size(); n++) {
|
||||
Frame *f = stack_order[n];
|
||||
if(f->window_type()==TYPE_DOCK || f->window_type()==TYPE_SPLASH) {
|
||||
windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
|
||||
windows[total++] = fl_xid(f);
|
||||
}
|
||||
}
|
||||
DBG("Restack: TOOLBAR, MENU");
|
||||
for(uint n=0; n<stack_order.size(); n++) {
|
||||
Frame *f = stack_order[n];
|
||||
if(f->window_type()==TYPE_TOOLBAR || f->window_type()==TYPE_MENU) {
|
||||
windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
|
||||
windows[total++] = fl_xid(f);
|
||||
}
|
||||
}
|
||||
DBG("Restack: NORMAL, UTIL, DIALOG");
|
||||
for(uint n=stack_order.size(); n--;) {
|
||||
Frame *f = stack_order[n];
|
||||
if( (f->window_type()==TYPE_NORMAL ||
|
||||
f->window_type()==TYPE_UTIL ||
|
||||
f->window_type()==TYPE_DIALOG) &&
|
||||
f->state()==NORMAL ) {
|
||||
windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
|
||||
windows[total++] = fl_xid(f);
|
||||
}
|
||||
}
|
||||
DBG("Restack: DESKTOP");
|
||||
for(uint n=0; n<stack_order.size(); n++) {
|
||||
Frame *f = stack_order[n];
|
||||
if(f->window_type()==TYPE_DESKTOP) {
|
||||
windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
|
||||
windows[total++] = fl_xid(f);
|
||||
}
|
||||
}
|
||||
|
||||
DBG("Restack: Call XRestackWindows!");
|
||||
if(total) XRestackWindows(fl_display, windows, total);
|
||||
delete []windows;
|
||||
}
|
||||
|
||||
void WindowManager::update_workarea(bool send)
|
||||
{
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
|
||||
for(uint n=0; n<map_order.size(); n++) {
|
||||
Frame *f = map_order[n];
|
||||
if( f->strut() && (f->desktop()==Desktop::current() || f->frame_flag(STICKY)) ) {
|
||||
left = max(left, f->strut()->left());
|
||||
right= max(right, f->strut()->right());
|
||||
top = max(top, f->strut()->top());
|
||||
bottom = max(bottom,f->strut()->bottom());
|
||||
}
|
||||
}
|
||||
wm_area.set(left, top, Fl::w()-(left+right), Fl::h()-(top+bottom));
|
||||
|
||||
for(uint n=stack_order.size(); n--;) {
|
||||
Frame *f = stack_order[n];
|
||||
if(f->maximized && f->state()==NORMAL) {
|
||||
int W=wm_area.w(), H=wm_area.h();
|
||||
W-=f->offset_w;
|
||||
H-=f->offset_h;
|
||||
ICCCM::get_size(f, W, H);
|
||||
W+=f->offset_w;
|
||||
H+=f->offset_h;
|
||||
|
||||
f->set_size(wm_area.x(), wm_area.y(), W, H);
|
||||
f->maximized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(send) {
|
||||
Desktop::update_desktop_workarea();
|
||||
Desktop::update_desktop_geometry();
|
||||
}
|
||||
}
|
||||
|
||||
//Updates NET client list atoms
|
||||
void WindowManager::update_client_list()
|
||||
{
|
||||
int i=0, client_count=0;
|
||||
Frame *f;
|
||||
|
||||
Window *net_map_order = 0;
|
||||
Window *net_stack_order = 0;
|
||||
|
||||
for(uint n=0; n<map_order.size(); n++) {
|
||||
f = map_order[n];
|
||||
if(!f->frame_flag(SKIP_LIST))
|
||||
client_count++;
|
||||
}
|
||||
if(!client_count) return;
|
||||
|
||||
net_map_order = new Window[client_count];
|
||||
net_stack_order = new Window[client_count];
|
||||
|
||||
i=0;
|
||||
for(uint n=0; n<stack_order.size(); n++) {
|
||||
f = stack_order[n];
|
||||
// We don't want to include transients in our client list
|
||||
if(!f->frame_flag(SKIP_LIST)) {
|
||||
net_stack_order[i++] = f->window();
|
||||
}
|
||||
}
|
||||
|
||||
i=0;
|
||||
for(uint n=0; n<map_order.size(); n++) {
|
||||
f = map_order[n];
|
||||
// We don't want to include transients in our client list
|
||||
if(!f->frame_flag(SKIP_LIST)) {
|
||||
net_map_order[i++] = f->window();
|
||||
}
|
||||
}
|
||||
|
||||
XChangeProperty(fl_display, fl_xid(root), _XA_NET_CLIENT_LIST, XA_WINDOW, 32, PropModeReplace, (unsigned char*)net_map_order, client_count);
|
||||
XChangeProperty(fl_display, fl_xid(root), _XA_NET_CLIENT_LIST_STACKING, XA_WINDOW, 32, PropModeReplace, (unsigned char*)net_stack_order, client_count);
|
||||
|
||||
delete []net_stack_order;
|
||||
delete []net_map_order;
|
||||
}
|
||||
|
||||
void WindowManager::idle()
|
||||
{
|
||||
for(uint n=remove_list.size(); n--;) {
|
||||
Frame *c = remove_list[n];
|
||||
delete c;
|
||||
}
|
||||
remove_list.clear();
|
||||
}
|
||||
|
||||
// Really really really quick fix, since this
|
||||
// solution sucks. Btw wm_shutdown is in main.cpp.
|
||||
extern bool wm_shutdown;
|
||||
void WindowManager::shutdown()
|
||||
{
|
||||
for(uint n = 0; n < map_order.size(); n++)
|
||||
{
|
||||
Frame* f = map_order[n];
|
||||
f->kill();
|
||||
}
|
||||
wm_shutdown = true;
|
||||
}
|
||||
|
||||
int WindowManager::handle(int e)
|
||||
{
|
||||
Window window = fl_xevent.xany.window;
|
||||
|
||||
switch(e) {
|
||||
case FL_PUSH:
|
||||
{
|
||||
for(uint n=stack_order.size(); n--;) {
|
||||
Frame *c = map_order[n];
|
||||
if (c->window() == window || fl_xid(c) == window) {
|
||||
c->content_click();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
DBG("Button press in root?!?!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
case FL_SHORTCUT:
|
||||
case FL_KEY:
|
||||
//case FL_KEYUP:
|
||||
return Handle_Hotkey();
|
||||
|
||||
case FL_MOUSEWHEEL:
|
||||
{
|
||||
XAllowEvents(fl_display, ReplayPointer, CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WindowManager::handle(XEvent *e)
|
||||
{
|
||||
switch(e->type)
|
||||
{
|
||||
case ClientMessage: {
|
||||
DBG("WindowManager ClientMessage 0x%lx", e->xclient.window);
|
||||
|
||||
if(handle_desktop_msgs(&(e->xclient))) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
case ConfigureRequest: {
|
||||
DBG("WindowManager ConfigureRequest: 0x%lx", e->xconfigurerequest.window);
|
||||
const XConfigureRequestEvent *e = &(fl_xevent.xconfigurerequest);
|
||||
XConfigureWindow(fl_display, e->window,
|
||||
e->value_mask&~(CWSibling|CWStackMode),
|
||||
(XWindowChanges*)&(e->x));
|
||||
return 1;
|
||||
}
|
||||
|
||||
case MapRequest: {
|
||||
DBG("WindowManager MapRequest: 0x%lx", e->xmaprequest.window);
|
||||
const XMapRequestEvent* e = &(fl_xevent.xmaprequest);
|
||||
new Frame(e->window);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WindowManager::handle_desktop_msgs(const XClientMessageEvent *e)
|
||||
{
|
||||
if(e->format!=32) return false;
|
||||
|
||||
if(e->message_type==_XA_NET_CURRENT_DESKTOP) {
|
||||
Desktop::current((int)e->data.l[0]+1);
|
||||
return true;
|
||||
} else
|
||||
if(e->message_type==_XA_NET_NUM_DESKTOPS) {
|
||||
DBG("New desk count: %ld", e->data.l[0]);
|
||||
Desktop::update_desktop_count(e->data.l[0]);
|
||||
// Set also new names...
|
||||
Desktop::set_names();
|
||||
return true;
|
||||
} else
|
||||
if(e->message_type==FLTKChangeSettings) {
|
||||
DBG("FLTK change settings");
|
||||
read_configuration();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
93
edewm/Windowmanager.h
Normal file
93
edewm/Windowmanager.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef _WINDOWMANAGER_H_
|
||||
#define _WINDOWMANAGER_H_
|
||||
|
||||
#include <efltk/Fl.h>
|
||||
#include <efltk/Fl_Window.h>
|
||||
#include <efltk/x.h>
|
||||
#include <efltk/fl_draw.h>
|
||||
#include <efltk/filename.h>
|
||||
|
||||
#include <efltk/Fl_Ptr_List.h>
|
||||
#include <efltk/Fl_Config.h>
|
||||
#include <efltk/Fl_Locale.h>
|
||||
#include "../exset/exset.h"
|
||||
|
||||
class Frame;
|
||||
|
||||
class Frame_List : public Fl_Ptr_List {
|
||||
public:
|
||||
Frame_List() : Fl_Ptr_List() { }
|
||||
|
||||
void append(Frame *item) { Fl_Ptr_List::append((void *)item); }
|
||||
void prepend(Frame *item) { Fl_Ptr_List::prepend((void *)item); }
|
||||
void insert(uint pos, Frame *item) { Fl_Ptr_List::insert(pos, (void *)item); }
|
||||
void replace(uint pos, Frame *item) { Fl_Ptr_List::replace(pos, (void *)item); }
|
||||
void remove(uint pos) { Fl_Ptr_List::remove(pos); }
|
||||
bool remove(Frame *item) { return Fl_Ptr_List::remove((void *)item); }
|
||||
int index_of(const Frame *w) const { return Fl_Ptr_List::index_of((void*)w); }
|
||||
Frame *item(uint index) const { return (Frame*)Fl_Ptr_List::item(index); }
|
||||
|
||||
Frame **data() { return (Frame**)items; }
|
||||
|
||||
Frame *operator [](uint ind) const { return (Frame *)items[ind]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// The WindowManager class looks like a window to efltk but is actually the
|
||||
// screen's root window. This is done by setting xid to "show" it
|
||||
// rather than have efltk create the window. Class handles all root
|
||||
// windows X events
|
||||
|
||||
class WindowManager : public Fl_Window
|
||||
{
|
||||
void init_wm(int argc, char *argv[]);
|
||||
Fl_Rect wm_area;
|
||||
Fl_Cursor cursor;
|
||||
Exset *xset;
|
||||
|
||||
public:
|
||||
WindowManager(int argc, char *argv[]);
|
||||
~WindowManager() { }
|
||||
|
||||
void set_default_cursor();
|
||||
void set_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg);
|
||||
void read_dispconf();
|
||||
Fl_Cursor get_cursor() { return cursor; }
|
||||
|
||||
void idle();
|
||||
int handle(int e);
|
||||
int handle(XEvent *e);
|
||||
|
||||
void show();
|
||||
void hide() { } //Prevent efltk to hide root window
|
||||
void draw();
|
||||
|
||||
void update_workarea(bool send=true);
|
||||
void shutdown();
|
||||
|
||||
Frame *find_by_wid(Window wid);
|
||||
void restack_windows();
|
||||
|
||||
//Updates GNOME and NET client list atoms
|
||||
static void update_client_list();
|
||||
static bool handle_desktop_msgs(const XClientMessageEvent *e);
|
||||
|
||||
int x() { return wm_area.x(); }
|
||||
int y() { return wm_area.y(); }
|
||||
int w() { return wm_area.w(); }
|
||||
int h() { return wm_area.h(); }
|
||||
|
||||
int XShapeEventBase, XShapeErrorBase;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
extern WindowManager *root;
|
||||
extern Window root_win;
|
||||
|
||||
extern Frame_List stack_order;
|
||||
extern Frame_List map_order;
|
||||
|
||||
extern Frame_List remove_list;
|
||||
#endif
|
333
edewm/Winhints.cpp
Normal file
333
edewm/Winhints.cpp
Normal file
@ -0,0 +1,333 @@
|
||||
#include "Frame.h"
|
||||
#include "Winhints.h"
|
||||
#include "Desktop.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
Atom _XA_UTF8_STRING;
|
||||
Atom _XA_SM_CLIENT_ID;
|
||||
|
||||
//ICCCM
|
||||
Atom _XA_WM_CLIENT_LEADER;
|
||||
Atom _XA_WM_PROTOCOLS;
|
||||
Atom _XA_WM_TAKE_FOCUS;
|
||||
Atom _XA_WM_DELETE_WINDOW;
|
||||
Atom _XA_WM_STATE;
|
||||
Atom _XA_WM_CHANGE_STATE;
|
||||
Atom _XA_WM_COLORMAP_WINDOWS;
|
||||
|
||||
//MWM
|
||||
Atom _XATOM_MWM_HINTS;
|
||||
Atom _XATOM_MOTIF_WM_INFO;
|
||||
|
||||
// Extended WM (NetWM)
|
||||
Atom _XA_NET_SUPPORTED;
|
||||
Atom _XA_NET_CLIENT_LIST;
|
||||
Atom _XA_NET_CLIENT_LIST_STACKING;
|
||||
Atom _XA_NET_NUM_DESKTOPS;
|
||||
Atom _XA_NET_DESKTOP_GEOMETRY;
|
||||
Atom _XA_NET_DESKTOP_VIEWPORT;
|
||||
Atom _XA_NET_CURRENT_DESKTOP;
|
||||
Atom _XA_NET_DESKTOP_NAMES;
|
||||
Atom _XA_NET_ACTIVE_WINDOW;
|
||||
Atom _XA_NET_WORKAREA;
|
||||
Atom _XA_NET_SUPPORTING_WM_CHECK;
|
||||
Atom _XA_NET_VIRTUAL_ROOTS;
|
||||
Atom _XA_NET_DESKTOP_LAYOUT;
|
||||
Atom _XA_NET_SHOWING_DESKTOP;
|
||||
Atom _XA_NET_CLOSE_WINDOW;
|
||||
Atom _XA_NET_WM_MOVERESIZE;
|
||||
Atom _XA_NET_RESTACK_WINDOW;
|
||||
Atom _XA_NET_REQUEST_FRAME_EXTENTS;
|
||||
Atom _XA_NET_WM_NAME;
|
||||
Atom _XA_NET_WM_VISIBLE_NAME;
|
||||
Atom _XA_NET_WM_ICON_NAME;
|
||||
Atom _XA_NET_WM_ICON_VISIBLE_NAME;
|
||||
Atom _XA_NET_WM_DESKTOP;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_DOCK;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_TOOLBAR;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_MENU;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_UTIL;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_SPLASH;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_DIALOG;
|
||||
Atom _XA_NET_WM_WINDOW_TYPE_NORMAL;
|
||||
Atom _XA_NET_WM_STATE;
|
||||
Atom _XA_NET_WM_STATE_MODAL;
|
||||
Atom _XA_NET_WM_STATE_STICKY;
|
||||
Atom _XA_NET_WM_STATE_MAXIMIZED_VERT;
|
||||
Atom _XA_NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
Atom _XA_NET_WM_STATE_SHADED;
|
||||
Atom _XA_NET_WM_STATE_SKIP_TASKBAR;
|
||||
Atom _XA_NET_WM_STATE_SKIP_PAGER;
|
||||
Atom _XA_NET_WM_STATE_HIDDEN; // new in spec. 1.3
|
||||
Atom _XA_NET_WM_STATE_FULLSCREEN; // new in spec. 1.3
|
||||
Atom _XA_NET_WM_STATE_ABOVE; // new in spec. 1.3
|
||||
Atom _XA_NET_WM_STATE_BELOW; // new in spec. 1.3
|
||||
Atom _XA_NET_WM_STATE_DEMANDS_ATTENTION; // new in spec. 1.3
|
||||
Atom _XA_NET_WM_ALLOWED_ACTIONS;
|
||||
Atom _XA_NET_WM_ACTION_MOVE;
|
||||
Atom _XA_NET_WM_ACTION_RESIZE;
|
||||
Atom _XA_NET_WM_ACTION_MINIMIZE;
|
||||
Atom _XA_NET_WM_ACTION_SHADE;
|
||||
Atom _XA_NET_WM_ACTION_STICK;
|
||||
Atom _XA_NET_WM_ACTION_MAXIMIZE_HORZ;
|
||||
Atom _XA_NET_WM_ACTION_MAXIMIZE_VERT;
|
||||
Atom _XA_NET_WM_ACTION_FULLSCREEN;
|
||||
Atom _XA_NET_WM_ACTION_CHANGE_DESKTOP;
|
||||
Atom _XA_NET_WM_ACTION_CLOSE;
|
||||
Atom _XA_NET_WM_STRUT;
|
||||
Atom _XA_NET_WM_STRUT_PARTIAL;
|
||||
Atom _XA_NET_WM_ICON_GEOMETRY;
|
||||
Atom _XA_NET_WM_ICON;
|
||||
Atom _XA_NET_WM_PID;
|
||||
Atom _XA_NET_WM_HANDLED_ICONS;
|
||||
Atom _XA_NET_WM_USER_TIME;
|
||||
Atom _XA_NET_FRAME_EXTENTS;
|
||||
Atom _XA_NET_WM_PING;
|
||||
Atom _XA_NET_WM_SYNC_REQUEST;
|
||||
Atom _XA_NET_WM_STATE_STAYS_ON_TOP;
|
||||
|
||||
//KDE1
|
||||
Atom _XA_KWM_WIN_ICON;
|
||||
|
||||
//EDE
|
||||
Atom _XA_EDE_WM_ACTION;
|
||||
Atom _XA_EDE_WM_LOGOUT;
|
||||
Atom _XA_EDE_WM_RESTORE_SIZE;
|
||||
|
||||
|
||||
|
||||
#define CNT(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
static bool atoms_inited = false;
|
||||
void init_atoms()
|
||||
{
|
||||
if(atoms_inited) return;
|
||||
|
||||
struct {
|
||||
Atom *atom;
|
||||
const char *name;
|
||||
} atom_info[] = {
|
||||
{ &_XA_UTF8_STRING, "UTF8_STRING" },
|
||||
{ &_XA_SM_CLIENT_ID, "SM_CLIENT_ID" },
|
||||
|
||||
//ICCCM
|
||||
{ &_XA_WM_PROTOCOLS, "WM_PROTOCOLS" },
|
||||
{ &_XA_WM_TAKE_FOCUS, "WM_TAKE_FOCUS" },
|
||||
{ &_XA_WM_DELETE_WINDOW, "WM_DELETE_WINDOW" },
|
||||
{ &_XA_WM_STATE, "WM_STATE" },
|
||||
{ &_XA_WM_CHANGE_STATE, "WM_CHANGE_STATE" },
|
||||
{ &_XA_WM_COLORMAP_WINDOWS, "WM_COLORMAP_WINDOWS" },
|
||||
{ &_XA_WM_CLIENT_LEADER, "WM_CLIENT_LEADER" },
|
||||
|
||||
//MWM
|
||||
{ &_XATOM_MWM_HINTS, _XA_MOTIF_WM_HINTS },
|
||||
{ &_XATOM_MOTIF_WM_INFO, _XA_MOTIF_WM_INFO },
|
||||
|
||||
//KDE1
|
||||
{ &_XA_KWM_WIN_ICON, "KWM_WIN_ICON" },
|
||||
|
||||
//Extended WM
|
||||
{ &_XA_NET_SUPPORTED, "_NET_SUPPORTED" },
|
||||
{ &_XA_NET_CLIENT_LIST, "_NET_CLIENT_LIST" },
|
||||
{ &_XA_NET_CLIENT_LIST_STACKING, "_NET_CLIENT_LIST_STACKING" },
|
||||
{ &_XA_NET_NUM_DESKTOPS, "_NET_NUMBER_OF_DESKTOPS" },
|
||||
{ &_XA_NET_DESKTOP_GEOMETRY,"_NET_DESKTOP_GEOMETRY" },
|
||||
{ &_XA_NET_DESKTOP_VIEWPORT,"_NET_DESKTOP_VIEWPORT" },
|
||||
{ &_XA_NET_CURRENT_DESKTOP, "_NET_CURRENT_DESKTOP" },
|
||||
{ &_XA_NET_DESKTOP_NAMES, "_NET_DESKTOP_NAMES" },
|
||||
{ &_XA_NET_ACTIVE_WINDOW, "_NET_ACTIVE_WINDOW" },
|
||||
{ &_XA_NET_WORKAREA, "_NET_WORKAREA" },
|
||||
{ &_XA_NET_SUPPORTING_WM_CHECK, "_NET_SUPPORTING_WM_CHECK" },
|
||||
{ &_XA_NET_VIRTUAL_ROOTS, "_NET_VIRTUAL_ROOTS" },
|
||||
{ &_XA_NET_DESKTOP_LAYOUT, "_NET_DESKTOP_LAYOUT" },
|
||||
{ &_XA_NET_SHOWING_DESKTOP, "_NET_SHOWING_DESKTOP" },
|
||||
{ &_XA_NET_CLOSE_WINDOW, "_NET_CLOSE_WINDOW" },
|
||||
{ &_XA_NET_WM_MOVERESIZE, "_NET_WM_MOVERESIZE" },
|
||||
{ &_XA_NET_RESTACK_WINDOW, "_NET_RESTACK_WINDOW" },
|
||||
{ &_XA_NET_REQUEST_FRAME_EXTENTS, "_NET_REQUEST_FRAME_EXTENTS" },
|
||||
{ &_XA_NET_WM_NAME, "_NET_WM_NAME" },
|
||||
{ &_XA_NET_WM_VISIBLE_NAME, "_NET_WM_VISIBLE_NAME" },
|
||||
{ &_XA_NET_WM_ICON_NAME, "_NET_WM_ICON_NAME" },
|
||||
{ &_XA_NET_WM_ICON_VISIBLE_NAME, "_NET_WM_ICON_VISIBLE_NAME" },
|
||||
{ &_XA_NET_WM_DESKTOP, "_NET_WM_DESKTOP" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE, "_NET_WM_WINDOW_TYPE" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_DESKTOP, "_NET_WM_WINDOW_TYPE_DESKTOP" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_DOCK, "_NET_WM_WINDOW_TYPE_DOCK" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_TOOLBAR, "_NET_WM_WINDOW_TYPE_TOOLBAR" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_MENU, "_NET_WM_WINDOW_TYPE_MENU" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_UTIL, "_NET_WM_WINDOW_TYPE_UTILITY" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_SPLASH, "_NET_WM_WINDOW_TYPE_SPLASH" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_DIALOG, "_NET_WM_WINDOW_TYPE_DIALOG" },
|
||||
{ &_XA_NET_WM_WINDOW_TYPE_NORMAL, "_NET_WM_WINDOW_TYPE_NORMAL" },
|
||||
{ &_XA_NET_WM_STATE, "_NET_WM_STATE" },
|
||||
{ &_XA_NET_WM_STATE_MODAL, "_NET_WM_STATE_MODAL" },
|
||||
{ &_XA_NET_WM_STATE_STICKY, "_NET_WM_STATE_STICKY" },
|
||||
{ &_XA_NET_WM_STATE_MAXIMIZED_VERT, "_NET_WM_STATE_MAXIMIZED_VERT" },
|
||||
{ &_XA_NET_WM_STATE_MAXIMIZED_HORZ, "_NET_WM_STATE_MAXIMIZED_HORZ" },
|
||||
{ &_XA_NET_WM_STATE_SHADED, "_NET_WM_STATE_SHADED" },
|
||||
{ &_XA_NET_WM_STATE_SKIP_TASKBAR, "_NET_WM_STATE_SKIP_TASKBAR" },
|
||||
{ &_XA_NET_WM_STATE_SKIP_PAGER, "_NET_WM_STATE_SKIP_PAGER" },
|
||||
{ &_XA_NET_WM_STATE_HIDDEN, "_NET_WM_STATE_HIDDEN" },
|
||||
{ &_XA_NET_WM_STATE_FULLSCREEN, "_NET_WM_STATE_FULLSCREEN" },
|
||||
{ &_XA_NET_WM_STATE_ABOVE, "_NET_WM_STATE_ABOVE" },
|
||||
{ &_XA_NET_WM_STATE_BELOW, "_NET_WM_STATE_BELOW" },
|
||||
{ &_XA_NET_WM_STATE_DEMANDS_ATTENTION, "_NET_WM_STATE_DEMANDS_ATTENTION" },
|
||||
{ &_XA_NET_WM_ALLOWED_ACTIONS, "_NET_WM_ALLOWED_ACTIONS" },
|
||||
{ &_XA_NET_WM_ACTION_MOVE, "_NET_WM_ACTION_MOVE" },
|
||||
{ &_XA_NET_WM_ACTION_RESIZE, "_NET_WM_ACTION_RESIZE" },
|
||||
{ &_XA_NET_WM_ACTION_MINIMIZE, "_NET_WM_ACTION_MINIMIZE" },
|
||||
{ &_XA_NET_WM_ACTION_SHADE, "_NET_WM_ACTION_SHADE" },
|
||||
{ &_XA_NET_WM_ACTION_STICK, "_NET_WM_ACTION_STICK" },
|
||||
{ &_XA_NET_WM_ACTION_MAXIMIZE_HORZ, "_NET_WM_ACTION_MAXIMIZE_HORZ" },
|
||||
{ &_XA_NET_WM_ACTION_MAXIMIZE_VERT, "_NET_WM_ACTION_MAXIMIZE_VERT" },
|
||||
{ &_XA_NET_WM_ACTION_FULLSCREEN, "_NET_WM_ACTION_FULLSCREEN" },
|
||||
{ &_XA_NET_WM_ACTION_CHANGE_DESKTOP, "_NET_WM_ACTION_CHANGE_DESKTOP" },
|
||||
{ &_XA_NET_WM_ACTION_CLOSE, "_NET_WM_ACTION_CLOSE" },
|
||||
{ &_XA_NET_WM_STRUT, "_NET_WM_STRUT" },
|
||||
{ &_XA_NET_WM_STRUT_PARTIAL, "_NET_WM_STRUT_PARTIAL" },
|
||||
{ &_XA_NET_WM_ICON_GEOMETRY, "_NET_WM_ICON_GEOMETRY" },
|
||||
{ &_XA_NET_WM_ICON, "_NET_WM_ICON" },
|
||||
{ &_XA_NET_WM_PID, "_NET_WM_PID" },
|
||||
{ &_XA_NET_WM_HANDLED_ICONS, "_NET_WM_HANDLED_ICONS" },
|
||||
{ &_XA_NET_WM_USER_TIME, "_NET_WM_USER_TIME" },
|
||||
{ &_XA_NET_FRAME_EXTENTS, "_NET_FRAME_EXTENTS" },
|
||||
{ &_XA_NET_WM_PING, "_NET_WM_PING" },
|
||||
{ &_XA_NET_WM_SYNC_REQUEST, "_NET_WM_SYNC_REQUEST" },
|
||||
/* the next one is not in the spec but KDE use it */
|
||||
{ &_XA_NET_WM_STATE_STAYS_ON_TOP, "_NET_WM_STATE_STAYS_ON_TOP" },
|
||||
/* KDE 1 */
|
||||
{ &_XA_KWM_WIN_ICON, "_NET_KWM_WIN_ICON" },
|
||||
/* EDE specific message */
|
||||
|
||||
{ &_XA_EDE_WM_ACTION, "_EDE_WM_ACTION" },
|
||||
{ &_XA_EDE_WM_LOGOUT, "_EDE_WM_LOGOUT" },
|
||||
{ &_XA_EDE_WM_RESTORE_SIZE, "_EDE_WM_RESTORE_SIZE" }
|
||||
|
||||
/*
|
||||
{ &_XA_CLIPBOARD, "CLIPBOARD" },
|
||||
{ &_XA_TARGETS, "TARGETS" },
|
||||
{ &XA_XdndAware, "XdndAware" },
|
||||
{ &XA_XdndEnter, "XdndEnter" },
|
||||
{ &XA_XdndLeave, "XdndLeave" },
|
||||
{ &XA_XdndPosition, "XdndPosition" },
|
||||
{ &XA_XdndStatus, "XdndStatus" },
|
||||
{ &XA_XdndDrop, "XdndDrop" },
|
||||
{ &XA_XdndFinished, "XdndFinished" }
|
||||
*/
|
||||
};
|
||||
|
||||
unsigned int i;
|
||||
for(i = 0; i < CNT(atom_info); i++) {
|
||||
*(atom_info[i].atom) = XInternAtom(fl_display, atom_info[i].name, False);
|
||||
}
|
||||
|
||||
atoms_inited = true;
|
||||
}
|
||||
|
||||
void register_protocols(Window root)
|
||||
{
|
||||
static bool protos_registered = false;
|
||||
if(protos_registered) return;
|
||||
|
||||
Atom net_proto[] = {
|
||||
_XA_NET_SUPPORTED,
|
||||
_XA_NET_CLIENT_LIST,
|
||||
_XA_NET_CLIENT_LIST_STACKING,
|
||||
_XA_NET_NUM_DESKTOPS,
|
||||
_XA_NET_DESKTOP_GEOMETRY,
|
||||
_XA_NET_DESKTOP_VIEWPORT,
|
||||
_XA_NET_SHOWING_DESKTOP,
|
||||
_XA_NET_CURRENT_DESKTOP,
|
||||
_XA_NET_DESKTOP_NAMES,
|
||||
_XA_NET_ACTIVE_WINDOW,
|
||||
_XA_NET_WORKAREA,
|
||||
_XA_NET_SUPPORTING_WM_CHECK,
|
||||
//_XA_NET_VIRTUAL_ROOTS, //hmmm.... I didnt understand this one...
|
||||
_XA_NET_CLOSE_WINDOW,
|
||||
//_XA_NET_WM_MOVERESIZE,
|
||||
_XA_NET_WM_NAME,
|
||||
//_XA_NET_WM_VISIBLE_NAME,
|
||||
_XA_NET_WM_ICON_NAME,
|
||||
//_XA_NET_WM_ICON_VISIBLE_NAME,
|
||||
_XA_NET_WM_DESKTOP,
|
||||
_XA_NET_WM_WINDOW_TYPE,
|
||||
_XA_NET_WM_WINDOW_TYPE_DESKTOP,
|
||||
_XA_NET_WM_WINDOW_TYPE_DOCK,
|
||||
_XA_NET_WM_WINDOW_TYPE_TOOLBAR,
|
||||
_XA_NET_WM_WINDOW_TYPE_MENU,
|
||||
_XA_NET_WM_WINDOW_TYPE_UTIL,
|
||||
_XA_NET_WM_WINDOW_TYPE_SPLASH,
|
||||
_XA_NET_WM_WINDOW_TYPE_DIALOG,
|
||||
_XA_NET_WM_WINDOW_TYPE_NORMAL,
|
||||
//_XA_NET_WM_STATE,
|
||||
//_XA_NET_WM_STATE_MODAL,
|
||||
//_XA_NET_WM_STATE_STICKY,
|
||||
//_XA_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
//_XA_NET_WM_STATE_MAXIMIZED_HORZ,
|
||||
//_XA_NET_WM_STATE_SHADED,
|
||||
//_XA_NET_WM_STATE_SKIP_TASKBAR,
|
||||
//_XA_NET_WM_STATE_SKIP_PAGER,
|
||||
// the next one is not in the spec but KDE use it
|
||||
//_XA_NET_WM_STATE_STAYS_ON_TOP,
|
||||
_XA_NET_WM_STRUT
|
||||
//_XA_NET_WM_ICON_GEOMETRY,
|
||||
//_XA_NET_WM_ICON,
|
||||
//_XA_NET_WM_PID,
|
||||
//_XA_NET_WM_HANDLED_ICONS,
|
||||
//_XA_NET_WM_PING
|
||||
};
|
||||
|
||||
//Set supported NET protos
|
||||
XChangeProperty(fl_display, root,
|
||||
_XA_NET_SUPPORTED, XA_ATOM, 32, PropModeReplace,
|
||||
(unsigned char *)net_proto, CNT(net_proto));
|
||||
|
||||
Window support_xid = XCreateSimpleWindow(fl_display, root, -200, -200, 5, 5, 0, 0, 0);
|
||||
|
||||
//NET:
|
||||
XChangeProperty(fl_display, support_xid,
|
||||
_XA_NET_SUPPORTING_WM_CHECK, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)&support_xid, 1);
|
||||
XChangeProperty(fl_display, root,
|
||||
_XA_NET_SUPPORTING_WM_CHECK, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)&support_xid, 1);
|
||||
|
||||
protos_registered = true;
|
||||
}
|
||||
|
||||
void Frame::get_protocols()
|
||||
{
|
||||
unsigned long n;
|
||||
Atom* p = (Atom*)getProperty(_XA_WM_PROTOCOLS, XA_ATOM, &n);
|
||||
if(p) {
|
||||
DBG("get_protocols()");
|
||||
clear_flag(DELETE_WIN_PRT|TAKE_FOCUS_PRT);
|
||||
for(unsigned int i = 0; i < n; ++i) {
|
||||
if(p[i]==_XA_WM_DELETE_WINDOW) {
|
||||
set_frame_flag(DELETE_WIN_PRT);
|
||||
} else if(p[i]==_XA_WM_TAKE_FOCUS) {
|
||||
set_frame_flag(TAKE_FOCUS_PRT);
|
||||
}
|
||||
}
|
||||
}
|
||||
XFree((char*)p);
|
||||
}
|
||||
|
||||
void Frame::get_wm_hints()
|
||||
{
|
||||
if(wm_hints) {
|
||||
XFree((char *)wm_hints);
|
||||
wm_hints = 0;
|
||||
}
|
||||
wm_hints = XGetWMHints(fl_display, window_);
|
||||
}
|
||||
|
||||
void Frame::update_wm_hints()
|
||||
{
|
||||
if(!wm_hints) return;
|
||||
if((wm_hints->flags & InputHint) && !wm_hints->input)
|
||||
set_frame_flag(NO_FOCUS);
|
||||
}
|
164
edewm/Winhints.h
Normal file
164
edewm/Winhints.h
Normal file
@ -0,0 +1,164 @@
|
||||
#ifndef _WINHINTS_H_
|
||||
#define _WINHINTS_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "Mwm.h"
|
||||
|
||||
//extern Atom _XA_SM_CLIENT_ID;
|
||||
|
||||
extern Atom _XA_UTF8_STRING;
|
||||
|
||||
// ICCCM
|
||||
extern Atom _XA_WM_CLIENT_LEADER;
|
||||
extern Atom _XA_WM_PROTOCOLS;
|
||||
extern Atom _XA_WM_TAKE_FOCUS;
|
||||
extern Atom _XA_WM_DELETE_WINDOW;
|
||||
extern Atom _XA_WM_STATE;
|
||||
extern Atom _XA_WM_CHANGE_STATE;
|
||||
extern Atom _XA_WM_COLORMAP_WINDOWS;
|
||||
|
||||
//MWM
|
||||
extern Atom _XATOM_MWM_HINTS;
|
||||
extern Atom _XATOM_MOTIF_WM_INFO;
|
||||
|
||||
// Extended WM Hints:
|
||||
// NetWM support
|
||||
// http://standards.freedesktop.org/wm-spec/
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
||||
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
|
||||
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
|
||||
#define _NET_WM_MOVERESIZE_MOVE 8 /* Movement only */
|
||||
//_NET_SUPPORTED, ATOM[]/32
|
||||
extern Atom _XA_NET_SUPPORTED;
|
||||
//_NET_CLIENT_LIST, XA_WINDOW[]/32
|
||||
extern Atom _XA_NET_CLIENT_LIST;
|
||||
//_NET_CLIENT_LIST_STACKING, XA_WINDOW[]/32
|
||||
extern Atom _XA_NET_CLIENT_LIST_STACKING;
|
||||
//_NET_NUMBER_OF_DESKTOPS, CARDINAL/32
|
||||
extern Atom _XA_NET_NUM_DESKTOPS;
|
||||
//_NET_DESKTOP_GEOMETRY width,height, CARDINAL[2]/32 | C
|
||||
extern Atom _XA_NET_DESKTOP_GEOMETRY;
|
||||
//_NET_DESKTOP_VIEWPORT x,y, CARDINAL[][2]/32 | C
|
||||
extern Atom _XA_NET_DESKTOP_VIEWPORT;
|
||||
//_NET_CURRENT_DESKTOP <desktop>, CARDINAL[1]/32 | C
|
||||
extern Atom _XA_NET_CURRENT_DESKTOP;
|
||||
//_NET_DESKTOP_NAMES, UTF8
|
||||
extern Atom _XA_NET_DESKTOP_NAMES;
|
||||
//_NET_ACTIVE_WINDOW, WINDOW/32
|
||||
extern Atom _XA_NET_ACTIVE_WINDOW;
|
||||
//_NET_WORKAREA, CARDINAL[][4]/32
|
||||
extern Atom _XA_NET_WORKAREA;
|
||||
//_NET_SUPPORTING_WM_CHECK, XA_WINDOW/32
|
||||
extern Atom _XA_NET_SUPPORTING_WM_CHECK;
|
||||
//_NET_VIRTUAL_ROOTS, XA_WINDOW[]/32
|
||||
extern Atom _XA_NET_VIRTUAL_ROOTS;
|
||||
//_NET_DESKTOP_LAYOUT, orientation, columns, rows, starting_corner CARDINAL[4]/32
|
||||
// (not implemented, used by pagers)
|
||||
extern Atom _XA_NET_DESKTOP_LAYOUT;
|
||||
//_NET_SHOWING_DESKTOP desktop, CARDINAL/32
|
||||
// (not implemented)
|
||||
extern Atom _XA_NET_SHOWING_DESKTOP;
|
||||
//_NET_CLOSE_WINDOW - closes active window
|
||||
extern Atom _XA_NET_CLOSE_WINDOW;
|
||||
//_NET_WM_MOVERESIZE | C
|
||||
extern Atom _XA_NET_WM_MOVERESIZE;
|
||||
//_NET_RESTACK_WINDOW
|
||||
// (not implemented, used by pagers)
|
||||
extern Atom _XA_NET_RESTACK_WINDOW;
|
||||
// _NET_REQUEST_FRAME_EXTENTS
|
||||
// (not implemented, used to detect frame size)
|
||||
extern Atom _XA_NET_REQUEST_FRAME_EXTENTS;
|
||||
//_NET_WM_NAME - UTF8
|
||||
extern Atom _XA_NET_WM_NAME;
|
||||
//_NET_WM_VISIBLE_NAME, UTF8
|
||||
extern Atom _XA_NET_WM_VISIBLE_NAME;
|
||||
//_NET_WM_ICON_NAME, UTF8
|
||||
extern Atom _XA_NET_WM_ICON_NAME;
|
||||
//_NET_WM_VISIBLE_ICON_NAME, UTF8
|
||||
extern Atom _XA_NET_WM_ICON_VISIBLE_NAME;
|
||||
//_NET_WM_DESKTOP <desktop>, CARDINAL/32 | C
|
||||
extern Atom _XA_NET_WM_DESKTOP;
|
||||
//_NET_WM_WINDOW_TYPE, ATOM[]/32
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE;
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP;
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_DOCK;
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_TOOLBAR;
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_MENU;
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_UTIL;
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_SPLASH;
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_DIALOG; //Transient type
|
||||
extern Atom _XA_NET_WM_WINDOW_TYPE_NORMAL; //Normal
|
||||
//_NET_WM_STATE, ATOM[] | C
|
||||
extern Atom _XA_NET_WM_STATE;
|
||||
extern Atom _XA_NET_WM_STATE_MODAL; //Needs transient for (root for whole group)
|
||||
extern Atom _XA_NET_WM_STATE_STICKY; //Pos fixed, even if virt. desk. scrolls
|
||||
extern Atom _XA_NET_WM_STATE_MAXIMIZED_VERT;
|
||||
extern Atom _XA_NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
extern Atom _XA_NET_WM_STATE_SHADED;
|
||||
extern Atom _XA_NET_WM_STATE_SKIP_TASKBAR;
|
||||
extern Atom _XA_NET_WM_STATE_SKIP_PAGER;
|
||||
extern Atom _XA_NET_WM_STATE_HIDDEN; // new in spec. 1.3
|
||||
extern Atom _XA_NET_WM_STATE_FULLSCREEN; // new in spec. 1.3
|
||||
extern Atom _XA_NET_WM_STATE_ABOVE; // new in spec. 1.3
|
||||
extern Atom _XA_NET_WM_STATE_BELOW; // new in spec. 1.3
|
||||
extern Atom _XA_NET_WM_STATE_DEMANDS_ATTENTION; // new in spec. 1.3
|
||||
//_NET_WM_ALLOWED_ACTIONS, ATOM[]
|
||||
// (not implemented, used to manipulate stuff from taskbar)
|
||||
extern Atom _XA_NET_WM_ALLOWED_ACTIONS;
|
||||
extern Atom _XA_NET_WM_ACTION_MOVE;
|
||||
extern Atom _XA_NET_WM_ACTION_RESIZE;
|
||||
extern Atom _XA_NET_WM_ACTION_MINIMIZE;
|
||||
extern Atom _XA_NET_WM_ACTION_SHADE;
|
||||
extern Atom _XA_NET_WM_ACTION_STICK;
|
||||
extern Atom _XA_NET_WM_ACTION_MAXIMIZE_HORZ;
|
||||
extern Atom _XA_NET_WM_ACTION_MAXIMIZE_VERT;
|
||||
extern Atom _XA_NET_WM_ACTION_FULLSCREEN;
|
||||
extern Atom _XA_NET_WM_ACTION_CHANGE_DESKTOP;
|
||||
extern Atom _XA_NET_WM_ACTION_CLOSE;
|
||||
//_NET_WM_STRUT, CARDINAL[4]/32
|
||||
extern Atom _XA_NET_WM_STRUT;
|
||||
//_NET_WM_STRUT_PARTIAL, left, right, top, bottom, left_start_y, left_end_y,
|
||||
//right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x,
|
||||
//bottom_end_x,CARDINAL[12]/32
|
||||
// (not implemented)
|
||||
extern Atom _XA_NET_WM_STRUT_PARTIAL;
|
||||
//_NET_WM_ICON_GEOMETRY, CARDINAL[4] - array of x,y,w,h of type CARDINAL, format 32
|
||||
extern Atom _XA_NET_WM_ICON_GEOMETRY;
|
||||
//_NET_WM_ICON CARDINAL[][2+n]/32 - 32bit packed CARDINAL ARGB with high byte being A, low byte being B
|
||||
extern Atom _XA_NET_WM_ICON;
|
||||
//_NET_WM_PID CARDINAL/32
|
||||
extern Atom _XA_NET_WM_PID;
|
||||
//_NET_WM_HANDLED_ICONS
|
||||
extern Atom _XA_NET_WM_HANDLED_ICONS;
|
||||
//_NET_WM_USER_TIME CARDINAL/32
|
||||
// (not implemented, used by e.g. autoaway in chat programs)
|
||||
extern Atom _XA_NET_WM_USER_TIME;
|
||||
//_NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
|
||||
// (not implemented, used to detect frame size)
|
||||
extern Atom _XA_NET_FRAME_EXTENTS;
|
||||
//_NET_WM_PING
|
||||
extern Atom _XA_NET_WM_PING;
|
||||
//_NET_WM_SYNC_REQUEST
|
||||
// (not implemented, used for XSync extension)
|
||||
extern Atom _XA_NET_WM_SYNC_REQUEST;
|
||||
// the next one is not in the spec but KDE use it
|
||||
// obsoleted by _NET_WM_STATE_ABOVE
|
||||
extern Atom _XA_NET_WM_STATE_STAYS_ON_TOP;
|
||||
|
||||
// KDE1 icon support, thats all of it :)
|
||||
extern Atom _XA_KWM_WIN_ICON;
|
||||
|
||||
// EDE specific message
|
||||
extern Atom _XA_EDE_WM_ACTION;
|
||||
extern Atom _XA_EDE_WM_LOGOUT;
|
||||
extern Atom _XA_EDE_WM_RESTORE_SIZE;
|
||||
|
||||
extern void init_atoms();
|
||||
extern void register_protocols(Window root);
|
||||
|
||||
#endif
|
40
edewm/config.h
Normal file
40
edewm/config.h
Normal file
@ -0,0 +1,40 @@
|
||||
// config.h
|
||||
// You can edit these symbols to change the behavior & appearance of flwm.
|
||||
// Turning off features will make flwm smaller too!
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// BEHAVIOR:
|
||||
|
||||
// Turn this on for click-to-type (rather than point-to-type).
|
||||
// On: clicking on the window gives it focus
|
||||
// Off: pointing at the window gives it the focus.
|
||||
#define CLICK_TO_TYPE 1
|
||||
|
||||
// For point-to-type, sticky focus means you don't lose the focus
|
||||
// until you move the cursor to another window that wants focus.
|
||||
// If this is off you lose focus as soon as the cursor goes outside
|
||||
// the window (such as to the desktop):
|
||||
#define STICKY_FOCUS 0
|
||||
|
||||
// For point-to-type, after this many seconds the window is raised,
|
||||
// nothing is done if this is not defined:
|
||||
//#define AUTO_RAISE 0.5
|
||||
|
||||
// set this to zero to remove the multiple-desktop code. This will
|
||||
// make flwm about 20K smaller
|
||||
#define DESKTOPS 1
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// APPEARANCE:
|
||||
|
||||
// how many pixels from edge for resize handle:
|
||||
#define RESIZE_EDGE 6
|
||||
|
||||
// must drag window this far off screen to snap the border off the screen:
|
||||
#define EDGE_SNAP 20
|
||||
// must drag window this far off screen to actually move it off screen:
|
||||
#define SCREEN_SNAP 40
|
||||
|
||||
#define SHAPE 1
|
||||
|
||||
|
9
edewm/debug.h
Normal file
9
edewm/debug.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef _DEBUG_H_
|
||||
#define _DEBUG_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
extern void DBG(const char *str, ...);
|
||||
|
||||
#endif
|
||||
|
88
edewm/locale/de.po
Normal file
88
edewm/locale/de.po
Normal file
@ -0,0 +1,88 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) 2006 THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the EDE package.
|
||||
# Ralf Eichinger <ralf.eichinger@pixotec.de>, 2006.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edewm 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-12-12 21:03+0100\n"
|
||||
"PO-Revision-Date: 2006-12-14 07:50+0100\n"
|
||||
"Last-Translator: Ralf Eichinger <ralf.eichinger@pixotec.de>\n"
|
||||
"Language-Team: German <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: edewm/Desktop.cpp:138 edewm/Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Arbeitsplatz %d"
|
||||
|
||||
#: edewm/Frame.cpp:146
|
||||
msgid "Untitled"
|
||||
msgstr "Ohne Titel"
|
||||
|
||||
#: edewm/Frame.cpp:977
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: edewm/Titlebar.cpp:225
|
||||
msgid "Sticky"
|
||||
msgstr "jeden Arbeitsplatz"
|
||||
|
||||
#: edewm/Titlebar.cpp:285 edewm/Titlebar.cpp:330
|
||||
msgid "Set size"
|
||||
msgstr "Größe ändern"
|
||||
|
||||
#: edewm/Titlebar.cpp:286
|
||||
msgid "Set size to window:"
|
||||
msgstr "Fenstergröße ändern auf:"
|
||||
|
||||
#: edewm/Titlebar.cpp:295
|
||||
msgid "width:"
|
||||
msgstr "Breite:"
|
||||
|
||||
#: edewm/Titlebar.cpp:297
|
||||
msgid "height:"
|
||||
msgstr "Höhe:"
|
||||
|
||||
#: edewm/Titlebar.cpp:301
|
||||
msgid "&OK"
|
||||
msgstr "&OK"
|
||||
|
||||
#: edewm/Titlebar.cpp:304
|
||||
msgid "&Cancel"
|
||||
msgstr "&Abbrechen"
|
||||
|
||||
#: edewm/Titlebar.cpp:328 edewm/Titlebar.cpp:341
|
||||
msgid "Maximize"
|
||||
msgstr "Maximieren"
|
||||
|
||||
#: edewm/Titlebar.cpp:329
|
||||
msgid "Minimize"
|
||||
msgstr "Minimieren"
|
||||
|
||||
#: edewm/Titlebar.cpp:331
|
||||
msgid "To Desktop"
|
||||
msgstr "Verschieben auf"
|
||||
|
||||
#: edewm/Titlebar.cpp:332
|
||||
msgid "Kill"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#: edewm/Titlebar.cpp:333
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: edewm/Titlebar.cpp:340
|
||||
msgid "Restore"
|
||||
msgstr "Wiederherstellen"
|
||||
|
||||
#: edewm/Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr "Ein anderer Fenstermanager läuft bereits. Beenden Sie diesen bevor Sie %s ausführen."
|
89
edewm/locale/fi.po
Normal file
89
edewm/locale/fi.po
Normal file
@ -0,0 +1,89 @@
|
||||
# Finnish translation of edewm.
|
||||
# Copyright (C) 2002 THE edewm'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the edewm package.
|
||||
# Mikko L. <Laza@Flashmail.com>, 2002.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edewm 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:33+0100\n"
|
||||
"PO-Revision-Date: 2002-09-16 11:07+0300\n"
|
||||
"Last-Translator: Mikko L. <Laza@Flashmail.com>\n"
|
||||
"Language-Team: Finnish <fi@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=iso-8859-15\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:138 Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Työpöytä %d"
|
||||
|
||||
#: Frame.cpp:106
|
||||
msgid "Untitled"
|
||||
msgstr "Nimetön"
|
||||
|
||||
#: Frame.cpp:938
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:215
|
||||
msgid "Sticky"
|
||||
msgstr "Kiinteä"
|
||||
|
||||
#: Titlebar.cpp:275 Titlebar.cpp:320
|
||||
msgid "Set size"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:276
|
||||
msgid "Set size to window:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:285
|
||||
msgid "width:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:287
|
||||
msgid "height:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:291
|
||||
msgid "&OK"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:294
|
||||
msgid "&Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:318 Titlebar.cpp:331
|
||||
msgid "Maximize"
|
||||
msgstr "Suurenna"
|
||||
|
||||
#: Titlebar.cpp:319
|
||||
msgid "Minimize"
|
||||
msgstr "Pienennä"
|
||||
|
||||
#: Titlebar.cpp:321
|
||||
msgid "To Desktop"
|
||||
msgstr "Työpöydälle:"
|
||||
|
||||
#: Titlebar.cpp:322
|
||||
msgid "Kill"
|
||||
msgstr "Tapa"
|
||||
|
||||
#: Titlebar.cpp:323
|
||||
msgid "Close"
|
||||
msgstr "Sulje"
|
||||
|
||||
#: Titlebar.cpp:330
|
||||
msgid "Restore"
|
||||
msgstr "Palauta"
|
||||
|
||||
#: Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr ""
|
||||
"Toinen ikkunointi järjestelmä käynnissä. Sinun täytyy lopettaa se ennen kuin "
|
||||
"voit ajaa: %s"
|
90
edewm/locale/fr.po
Normal file
90
edewm/locale/fr.po
Normal file
@ -0,0 +1,90 @@
|
||||
# French translation of ede.
|
||||
# Copyright (C) 2007 THE ede'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the ede package.
|
||||
# emmanuel coutant <ecoutan@cegetel.net>, 2007.
|
||||
# , fuzzy
|
||||
#
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ede 1.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-01-07 14:49+0100\n"
|
||||
"PO-Revision-Date: 2007-01-07 16:41+0100\n"
|
||||
"Last-Translator: emmanuel coutant <ecoutan@cegetel.net>\n"
|
||||
"Language-Team: French\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit"
|
||||
|
||||
#: edewm/Desktop.cpp:138 edewm/Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Bureau %d"
|
||||
|
||||
#: edewm/Frame.cpp:146
|
||||
msgid "Untitled"
|
||||
msgstr "Sans titre"
|
||||
|
||||
#: edewm/Frame.cpp:977
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: edewm/Titlebar.cpp:225
|
||||
msgid "Sticky"
|
||||
msgstr "Punaiser"
|
||||
|
||||
#: edewm/Titlebar.cpp:285 edewm/Titlebar.cpp:330
|
||||
msgid "Set size"
|
||||
msgstr "Redimensionner"
|
||||
|
||||
#: edewm/Titlebar.cpp:286
|
||||
msgid "Set size to window:"
|
||||
msgstr ""
|
||||
|
||||
#: edewm/Titlebar.cpp:295
|
||||
msgid "width:"
|
||||
msgstr "Largeur:"
|
||||
|
||||
#: edewm/Titlebar.cpp:297
|
||||
msgid "height:"
|
||||
msgstr "Hauteur:"
|
||||
|
||||
#: edewm/Titlebar.cpp:301
|
||||
msgid "&OK"
|
||||
msgstr "&OK"
|
||||
|
||||
#: edewm/Titlebar.cpp:304
|
||||
msgid "&Cancel"
|
||||
msgstr "&Annuler"
|
||||
|
||||
#: edewm/Titlebar.cpp:328 edewm/Titlebar.cpp:341
|
||||
msgid "Maximize"
|
||||
msgstr "Maximiser"
|
||||
|
||||
#: edewm/Titlebar.cpp:329
|
||||
msgid "Minimize"
|
||||
msgstr "Minimiser"
|
||||
|
||||
#: edewm/Titlebar.cpp:331
|
||||
msgid "To Desktop"
|
||||
msgstr "Vers le bureau"
|
||||
|
||||
#: edewm/Titlebar.cpp:332
|
||||
msgid "Kill"
|
||||
msgstr "Tuer"
|
||||
|
||||
#: edewm/Titlebar.cpp:333
|
||||
msgid "Close"
|
||||
msgstr "Fermer"
|
||||
|
||||
#: edewm/Titlebar.cpp:340
|
||||
msgid "Restore"
|
||||
msgstr "Restaurer"
|
||||
|
||||
#: edewm/Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr "Un autre gestionnaire de fenêtre est actif. Vous devez le quitter avant de démarrer %s."
|
||||
|
BIN
edewm/locale/hu.mo
Normal file
BIN
edewm/locale/hu.mo
Normal file
Binary file not shown.
85
edewm/locale/hu.po
Normal file
85
edewm/locale/hu.po
Normal file
@ -0,0 +1,85 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: 2005-02-09 11:21+0100\n"
|
||||
"Last-Translator: Nemeth Otto <otto_nemeth@freemail.hu>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:138
|
||||
#: Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Munkaterület %d"
|
||||
|
||||
#: Frame.cpp:106
|
||||
msgid "Untitled"
|
||||
msgstr "Névtelen"
|
||||
|
||||
#: Frame.cpp:938
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr "EDEWM: Belső hiba, restacking (%d != %d)! Kilépés... "
|
||||
|
||||
#: Titlebar.cpp:215
|
||||
msgid "Sticky"
|
||||
msgstr "Ragadós"
|
||||
|
||||
#: Titlebar.cpp:275
|
||||
#: Titlebar.cpp:320
|
||||
msgid "Set size"
|
||||
msgstr "Méret beállítása"
|
||||
|
||||
#: Titlebar.cpp:276
|
||||
msgid "Set size to window:"
|
||||
msgstr "Ablakméret beállítása:"
|
||||
|
||||
#: Titlebar.cpp:285
|
||||
msgid "width:"
|
||||
msgstr "szél.:"
|
||||
|
||||
#: Titlebar.cpp:287
|
||||
msgid "height:"
|
||||
msgstr "mag.:"
|
||||
|
||||
#: Titlebar.cpp:291
|
||||
msgid "&OK"
|
||||
msgstr "&OK"
|
||||
|
||||
#: Titlebar.cpp:294
|
||||
msgid "&Cancel"
|
||||
msgstr "Mégs&em"
|
||||
|
||||
#: Titlebar.cpp:318
|
||||
#: Titlebar.cpp:331
|
||||
msgid "Maximize"
|
||||
msgstr "Maximalizálás"
|
||||
|
||||
#: Titlebar.cpp:319
|
||||
msgid "Minimize"
|
||||
msgstr "Minimalizálás"
|
||||
|
||||
#: Titlebar.cpp:321
|
||||
msgid "To Desktop"
|
||||
msgstr "Munkaterületre"
|
||||
|
||||
#: Titlebar.cpp:322
|
||||
msgid "Kill"
|
||||
msgstr "Kilövés"
|
||||
|
||||
#: Titlebar.cpp:323
|
||||
msgid "Close"
|
||||
msgstr "Bezárás"
|
||||
|
||||
#: Titlebar.cpp:330
|
||||
msgid "Restore"
|
||||
msgstr "Visszaállítás"
|
||||
|
||||
#: Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr "Egy másik ablakkezelő fut. Ki kell lépni belőle mielőtt ezt futtatod: %s."
|
||||
|
89
edewm/locale/id.po
Normal file
89
edewm/locale/id.po
Normal file
@ -0,0 +1,89 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edewm 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:33+0100\n"
|
||||
"PO-Revision-Date: 202-11-29 14:20+0700\n"
|
||||
"Last-Translator: Bambang Purnomosidi D. P. <i-am-the-boss@bpdp.org>\n"
|
||||
"Language-Team: id <i-am-the-boss@bpdp.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=iso-8859-2\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:138 Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Ruangkerja %d"
|
||||
|
||||
#: Frame.cpp:106
|
||||
msgid "Untitled"
|
||||
msgstr "Tanpa judul"
|
||||
|
||||
#: Frame.cpp:938
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:215
|
||||
msgid "Sticky"
|
||||
msgstr "Sticky"
|
||||
|
||||
#: Titlebar.cpp:275 Titlebar.cpp:320
|
||||
msgid "Set size"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:276
|
||||
msgid "Set size to window:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:285
|
||||
msgid "width:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:287
|
||||
msgid "height:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:291
|
||||
msgid "&OK"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:294
|
||||
msgid "&Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:318 Titlebar.cpp:331
|
||||
msgid "Maximize"
|
||||
msgstr "Maksimalkan"
|
||||
|
||||
#: Titlebar.cpp:319
|
||||
msgid "Minimize"
|
||||
msgstr "Minimalkan"
|
||||
|
||||
#: Titlebar.cpp:321
|
||||
msgid "To Desktop"
|
||||
msgstr "Ke Desktop"
|
||||
|
||||
#: Titlebar.cpp:322
|
||||
msgid "Kill"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:323
|
||||
msgid "Close"
|
||||
msgstr "Tutup"
|
||||
|
||||
#: Titlebar.cpp:330
|
||||
msgid "Restore"
|
||||
msgstr "Kembalikan"
|
||||
|
||||
#: Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr ""
|
||||
"Window manager lain sedang berjalan. Anda harus menghentikannya sebelum "
|
||||
"menjalankan %s."
|
63
edewm/locale/messages.po.default
Normal file
63
edewm/locale/messages.po.default
Normal file
@ -0,0 +1,63 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#: Desktop.cpp:233 Windowmanager.cpp:97
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2002-09-16 10:58+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:247
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr ""
|
||||
|
||||
|
||||
|
||||
#: Frame.cpp:134 main.cpp:51
|
||||
msgid "Untitled"
|
||||
msgstr ""
|
||||
|
||||
|
||||
|
||||
#: Titlebar.cpp:211
|
||||
msgid "Sticky"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:247 Titlebar.cpp:257
|
||||
msgid "Maximize"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:248
|
||||
msgid "Minimize"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:249
|
||||
msgid "To Desktop"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:250
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:272
|
||||
msgid "Kill"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:256
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: Windowmanager.cpp:88
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr ""
|
88
edewm/locale/messages.pot
Normal file
88
edewm/locale/messages.pot
Normal file
@ -0,0 +1,88 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:33+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:138 Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr ""
|
||||
|
||||
#: Frame.cpp:106
|
||||
msgid "Untitled"
|
||||
msgstr ""
|
||||
|
||||
#: Frame.cpp:938
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:215
|
||||
msgid "Sticky"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:275 Titlebar.cpp:320
|
||||
msgid "Set size"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:276
|
||||
msgid "Set size to window:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:285
|
||||
msgid "width:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:287
|
||||
msgid "height:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:291
|
||||
msgid "&OK"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:294
|
||||
msgid "&Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:318 Titlebar.cpp:331
|
||||
msgid "Maximize"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:319
|
||||
msgid "Minimize"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:321
|
||||
msgid "To Desktop"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:322
|
||||
msgid "Kill"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:323
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:330
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr ""
|
BIN
edewm/locale/ru.mo
Normal file
BIN
edewm/locale/ru.mo
Normal file
Binary file not shown.
90
edewm/locale/ru.po
Normal file
90
edewm/locale/ru.po
Normal file
@ -0,0 +1,90 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:33+0100\n"
|
||||
"PO-Revision-Date: 2002-11-28 HO:MI+ZONE\n"
|
||||
"Last-Translator: aabbvv <null@list.ru>\n"
|
||||
"Language-Team: RUSSIAN <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=koi8-r\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:138 Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "òÁÂÏÞÉÊ ÓÔÏÌ %d"
|
||||
|
||||
#: Frame.cpp:106
|
||||
msgid "Untitled"
|
||||
msgstr "îÅÐÏÉÍÅÎÏ×ÁÎÎÙÊ"
|
||||
|
||||
#: Frame.cpp:938
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:215
|
||||
msgid "Sticky"
|
||||
msgstr "÷ÓÅ ÓÒÁÚÕ"
|
||||
|
||||
#: Titlebar.cpp:275 Titlebar.cpp:320
|
||||
msgid "Set size"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:276
|
||||
msgid "Set size to window:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:285
|
||||
msgid "width:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:287
|
||||
msgid "height:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:291
|
||||
msgid "&OK"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:294
|
||||
msgid "&Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:318 Titlebar.cpp:331
|
||||
msgid "Maximize"
|
||||
msgstr "òÁÚ×ÅÒÎÕÔØ"
|
||||
|
||||
#: Titlebar.cpp:319
|
||||
msgid "Minimize"
|
||||
msgstr "ó×ÅÒÎÕÔØ"
|
||||
|
||||
#: Titlebar.cpp:321
|
||||
msgid "To Desktop"
|
||||
msgstr "îÁ ÒÁÂÏÞÉÊ ÓÔÏÌ"
|
||||
|
||||
#: Titlebar.cpp:322
|
||||
msgid "Kill"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:323
|
||||
msgid "Close"
|
||||
msgstr "úÁËÒÙÔØ"
|
||||
|
||||
#: Titlebar.cpp:330
|
||||
msgid "Restore"
|
||||
msgstr "÷ÏÓÓÔÁÎÏ×ÉÔØ"
|
||||
|
||||
#: Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr ""
|
||||
"úÁÐÕÝÅÎ ÄÒÕÇÏÊ ÏËÏÎÎÙÊ ÍÅÎÅÄÖÅÒ. îÅÏÂÈÏÄÉÍÏ ×ÙÊÔÉ ÉÈ ÎÅÇÏ ÐÅÒÅ ÔÅÍ ËÁË "
|
||||
"ÚÁÐÕÓÔÉÔØ %s."
|
BIN
edewm/locale/sk.mo
Normal file
BIN
edewm/locale/sk.mo
Normal file
Binary file not shown.
87
edewm/locale/sk.po
Normal file
87
edewm/locale/sk.po
Normal file
@ -0,0 +1,87 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edewm 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:33+0100\n"
|
||||
"PO-Revision-Date: 2002-04-21 14:50+0200\n"
|
||||
"Last-Translator: Martin Pekar <cortex@nextra.sk>\n"
|
||||
"Language-Team: Slovak <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:138 Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Plocha %d"
|
||||
|
||||
#: Frame.cpp:106
|
||||
msgid "Untitled"
|
||||
msgstr "Bez názvu"
|
||||
|
||||
#: Frame.cpp:938
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:215
|
||||
msgid "Sticky"
|
||||
msgstr "Lepkavý"
|
||||
|
||||
#: Titlebar.cpp:275 Titlebar.cpp:320
|
||||
msgid "Set size"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:276
|
||||
msgid "Set size to window:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:285
|
||||
msgid "width:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:287
|
||||
msgid "height:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:291
|
||||
msgid "&OK"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:294
|
||||
msgid "&Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:318 Titlebar.cpp:331
|
||||
msgid "Maximize"
|
||||
msgstr "Maximalizovať"
|
||||
|
||||
#: Titlebar.cpp:319
|
||||
msgid "Minimize"
|
||||
msgstr "Minimalizovať"
|
||||
|
||||
#: Titlebar.cpp:321
|
||||
msgid "To Desktop"
|
||||
msgstr "Na plochu"
|
||||
|
||||
#: Titlebar.cpp:322
|
||||
msgid "Kill"
|
||||
msgstr "Ukončiť"
|
||||
|
||||
#: Titlebar.cpp:323
|
||||
msgid "Close"
|
||||
msgstr "Zavrieť"
|
||||
|
||||
#: Titlebar.cpp:330
|
||||
msgid "Restore"
|
||||
msgstr "Obnoviť"
|
||||
|
||||
#: Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr ""
|
||||
"Práve beží už iný manažér okien. Musíte ho ukončiť a chcete spustiť %s."
|
BIN
edewm/locale/sr.mo
Normal file
BIN
edewm/locale/sr.mo
Normal file
Binary file not shown.
87
edewm/locale/sr.po
Normal file
87
edewm/locale/sr.po
Normal file
@ -0,0 +1,87 @@
|
||||
# EDEWM - Prevod na srpski jezik
|
||||
# Copyright (C) 2002 EDE Team
|
||||
# Dejan Lekic Dejan Lekic <dejan@nu6.org>, 2002.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: EDEWM 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:33+0100\n"
|
||||
"PO-Revision-Date: 2002-11-21 08:26+0100\n"
|
||||
"Last-Translator: Dejan Lekic <dejan@nu6.org>\n"
|
||||
"Language-Team: LINUKS.org T.T. <i18n@linuks.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: Desktop.cpp:138 Desktop.cpp:180
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Радни простор %d"
|
||||
|
||||
#: Frame.cpp:106
|
||||
msgid "Untitled"
|
||||
msgstr "Неименован"
|
||||
|
||||
#: Frame.cpp:938
|
||||
#, c-format
|
||||
msgid "EDEWM: Internal bug, when restacking (%d != %d)! Exiting... "
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:215
|
||||
msgid "Sticky"
|
||||
msgstr "Стики"
|
||||
|
||||
#: Titlebar.cpp:275 Titlebar.cpp:320
|
||||
msgid "Set size"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:276
|
||||
msgid "Set size to window:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:285
|
||||
msgid "width:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:287
|
||||
msgid "height:"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:291
|
||||
msgid "&OK"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:294
|
||||
msgid "&Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:318 Titlebar.cpp:331
|
||||
msgid "Maximize"
|
||||
msgstr "Максимизуј"
|
||||
|
||||
#: Titlebar.cpp:319
|
||||
msgid "Minimize"
|
||||
msgstr "Минимизуј"
|
||||
|
||||
#: Titlebar.cpp:321
|
||||
msgid "To Desktop"
|
||||
msgstr "На десктоп"
|
||||
|
||||
#: Titlebar.cpp:322
|
||||
msgid "Kill"
|
||||
msgstr ""
|
||||
|
||||
#: Titlebar.cpp:323
|
||||
msgid "Close"
|
||||
msgstr "Затвори"
|
||||
|
||||
#: Titlebar.cpp:330
|
||||
msgid "Restore"
|
||||
msgstr "Врати"
|
||||
|
||||
#: Windowmanager.cpp:90
|
||||
#, c-format
|
||||
msgid "Another window manager is running. You must exit it before running %s."
|
||||
msgstr ""
|
||||
"Други менаџер прозора је активан. Мораћете га угасити пре покретања %s."
|
68
edewm/main.cpp
Normal file
68
edewm/main.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "Frame.h"
|
||||
#include "Desktop.h"
|
||||
#include "Windowmanager.h"
|
||||
|
||||
#include <efltk/filename.h>
|
||||
#include <efltk/fl_draw.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include <edeconf.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
bool wm_shutdown = false;
|
||||
|
||||
void exit_signal(int signum)
|
||||
{
|
||||
printf("EDEWM: Exiting (got signal %d)\n", signum);
|
||||
wm_shutdown = true;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
signal(SIGTERM, exit_signal);
|
||||
signal(SIGKILL, exit_signal);
|
||||
signal(SIGINT, exit_signal);
|
||||
|
||||
Fl::args(argc, argv);
|
||||
|
||||
fl_init_locale_support("edewm", PREFIX"/share/locale");
|
||||
|
||||
WindowManager wm(argc, argv);
|
||||
root = &wm;
|
||||
|
||||
Fl_Style::load_theme();
|
||||
|
||||
while(!wm_shutdown) {
|
||||
Fl::wait();
|
||||
wm.idle();
|
||||
}
|
||||
|
||||
Frame_List l(map_order);
|
||||
for(uint n=0; n<l.size(); n++) {
|
||||
Frame *f = l[n];
|
||||
delete f;
|
||||
}
|
||||
DBG("Going down");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DBG(const char *str, ...)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
fprintf(stderr, "EDEWM DEBUG: ");
|
||||
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
vfprintf(stderr, str, args);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
#endif
|
||||
}
|
258
edewm/tux.xpm
Normal file
258
edewm/tux.xpm
Normal file
@ -0,0 +1,258 @@
|
||||
/* XPM */
|
||||
static const char * tux_xpm[] = {
|
||||
"48 48 207 2",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #858585",
|
||||
"@ c #333333",
|
||||
"# c #7F7F7F",
|
||||
"$ c #BABABA",
|
||||
"% c #B8B8B8",
|
||||
"& c #C1C1C1",
|
||||
"* c #2D2D2D",
|
||||
"= c #C6C6C6",
|
||||
"- c #D9D9D9",
|
||||
"; c #8A8A8A",
|
||||
"> c #BBBBBB",
|
||||
", c #C9C9C9",
|
||||
"' c #9C9C9C",
|
||||
") c #EDEDED",
|
||||
"! c #D7D7D7",
|
||||
"~ c #888888",
|
||||
"{ c #DEDEDE",
|
||||
"] c #E9E9E9",
|
||||
"^ c #EAEAEA",
|
||||
"/ c #C2C2C2",
|
||||
"( c #EBEBEB",
|
||||
"_ c #BEBEBE",
|
||||
": c #262626",
|
||||
"< c #929292",
|
||||
"[ c #999999",
|
||||
"} c #828282",
|
||||
"| c #F3F3F3",
|
||||
"1 c #DDDDDD",
|
||||
"2 c #ABABAB",
|
||||
"3 c #DCAF00",
|
||||
"4 c #FFDC00",
|
||||
"5 c #939393",
|
||||
"6 c #878787",
|
||||
"7 c #F2F2F2",
|
||||
"8 c #FFF793",
|
||||
"9 c #FFF148",
|
||||
"0 c #FFE957",
|
||||
"a c #EFE3A3",
|
||||
"b c #482D00",
|
||||
"c c #424242",
|
||||
"d c #AF6800",
|
||||
"e c #FFF461",
|
||||
"f c #FFF1C1",
|
||||
"g c #FFF1B5",
|
||||
"h c #FFE600",
|
||||
"i c #E1B500",
|
||||
"j c #815200",
|
||||
"k c #484848",
|
||||
"l c #EBC200",
|
||||
"m c #FFEB84",
|
||||
"n c #FFE71C",
|
||||
"o c #C99300",
|
||||
"p c #610000",
|
||||
"q c #343434",
|
||||
"r c #DBC975",
|
||||
"s c #D8AA00",
|
||||
"t c #D9AB00",
|
||||
"u c #B57300",
|
||||
"v c #C08500",
|
||||
"w c #E3B800",
|
||||
"x c #2D0000",
|
||||
"y c #636363",
|
||||
"z c #A1A1A1",
|
||||
"A c #EEEEEE",
|
||||
"B c #E9D677",
|
||||
"C c #CC9A00",
|
||||
"D c #DFB300",
|
||||
"E c #E7BE00",
|
||||
"F c #EDD700",
|
||||
"G c #EEE3AD",
|
||||
"H c #666666",
|
||||
"I c #8D8D8D",
|
||||
"J c #B2B2B2",
|
||||
"K c #3F3F3F",
|
||||
"L c #D1D1D1",
|
||||
"M c #F1F1F1",
|
||||
"N c #E8E8E8",
|
||||
"O c #DADADA",
|
||||
"P c #ECECEC",
|
||||
"Q c #DFDFDF",
|
||||
"R c #818181",
|
||||
"S c #393939",
|
||||
"T c #676767",
|
||||
"U c #D3D3D3",
|
||||
"V c #F0F0F0",
|
||||
"W c #D2D2D2",
|
||||
"X c #CACACA",
|
||||
"Y c #C4C4C4",
|
||||
"Z c #646464",
|
||||
"` c #D8D8D8",
|
||||
" . c #F5F5F5",
|
||||
".. c #F7F7F7",
|
||||
"+. c #F8F8F8",
|
||||
"@. c #CDCDCD",
|
||||
"#. c #EFEFEF",
|
||||
"$. c #E4E4E4",
|
||||
"%. c #FAFAFA",
|
||||
"&. c #E7E7E7",
|
||||
"*. c #E1E1E1",
|
||||
"=. c #DCDCDC",
|
||||
"-. c #C7C7C7",
|
||||
";. c #898989",
|
||||
">. c #FBFBFB",
|
||||
",. c #F9F9F9",
|
||||
"'. c #8E8E8E",
|
||||
"). c #D5D5D5",
|
||||
"!. c #E3E3E3",
|
||||
"~. c #AFAFAF",
|
||||
"{. c #E6E6E6",
|
||||
"]. c #D0D0D0",
|
||||
"^. c #E5E5E5",
|
||||
"/. c #E0E0E0",
|
||||
"(. c #767676",
|
||||
"_. c #414141",
|
||||
":. c #E1E0DF",
|
||||
"<. c #575757",
|
||||
"[. c #959595",
|
||||
"}. c #FCF8E8",
|
||||
"|. c #F9F3DB",
|
||||
"1. c #E2E2E2",
|
||||
"2. c #1C0000",
|
||||
"3. c #F7EFC6",
|
||||
"4. c #A49F8F",
|
||||
"5. c #5F5D51",
|
||||
"6. c #D9D2BB",
|
||||
"7. c #FFEA66",
|
||||
"8. c #D8B400",
|
||||
"9. c #B4B4B4",
|
||||
"0. c #D9D9D7",
|
||||
"a. c #614800",
|
||||
"b. c #FCF7E3",
|
||||
"c. c #CBA900",
|
||||
"d. c #9B7300",
|
||||
"e. c #8A7C00",
|
||||
"f. c #521C00",
|
||||
"g. c #1C1A00",
|
||||
"h. c #CCC9C2",
|
||||
"i. c #FAF3D8",
|
||||
"j. c #FFED92",
|
||||
"k. c #FBD700",
|
||||
"l. c #F7D300",
|
||||
"m. c #D7B300",
|
||||
"n. c #616161",
|
||||
"o. c #D6D6D5",
|
||||
"p. c #684C00",
|
||||
"q. c #FBF3C9",
|
||||
"r. c #FAD700",
|
||||
"s. c #E0BD00",
|
||||
"t. c #BB9600",
|
||||
"u. c #E3C000",
|
||||
"v. c #9A9382",
|
||||
"w. c #E7DFBC",
|
||||
"x. c #D4CDA8",
|
||||
"y. c #FFE400",
|
||||
"z. c #F2CF00",
|
||||
"A. c #EECB00",
|
||||
"B. c #D7B400",
|
||||
"C. c #CCCCCC",
|
||||
"D. c #5F5F5F",
|
||||
"E. c #FBF0C3",
|
||||
"F. c #F9D700",
|
||||
"G. c #FDDA00",
|
||||
"H. c #C9B400",
|
||||
"I. c #EEDA55",
|
||||
"J. c #E9C700",
|
||||
"K. c #938500",
|
||||
"L. c #DED086",
|
||||
"M. c #EAC700",
|
||||
"N. c #C9A700",
|
||||
"O. c #979797",
|
||||
"P. c #BFBFBF",
|
||||
"Q. c #A6A6A6",
|
||||
"R. c #989898",
|
||||
"S. c #595959",
|
||||
"T. c #F8EFC3",
|
||||
"U. c #F7D400",
|
||||
"V. c #EDCB00",
|
||||
"W. c #D3B400",
|
||||
"X. c #877000",
|
||||
"Y. c #E7DDAA",
|
||||
"Z. c #FBE100",
|
||||
"`. c #DCB900",
|
||||
" + c #947300",
|
||||
".+ c #F5ECC3",
|
||||
"++ c #EBC900",
|
||||
"@+ c #F3CF00",
|
||||
"#+ c #EFCC00",
|
||||
"$+ c #E6C200",
|
||||
"%+ c #B39600",
|
||||
"&+ c #A99500",
|
||||
"*+ c #DCB800",
|
||||
"=+ c #D3B000",
|
||||
"-+ c #CFAC00",
|
||||
";+ c #AF8A00",
|
||||
">+ c #836300",
|
||||
",+ c #EDE09B",
|
||||
"'+ c #EAD866",
|
||||
")+ c #E1BE00",
|
||||
"!+ c #B79A00",
|
||||
"~+ c #9A8100",
|
||||
"{+ c #605721",
|
||||
"]+ c #9D8B21",
|
||||
"^+ c #968319",
|
||||
"/+ c #746100",
|
||||
"(+ c #211E0D",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" . . ",
|
||||
" . . . . . . . + ",
|
||||
" . . . . @ # $ # . ",
|
||||
" . . . . . . . % & . . ",
|
||||
" . . . . . . . . * . . . ",
|
||||
" . . . . . . . . . . . . . ",
|
||||
" . . = - ; . . > , . . . . ",
|
||||
" . ' ) ) ! ~ { ] ^ / . . . ",
|
||||
" . ( _ : < [ = . } | . . . ",
|
||||
" . 1 2 . 3 4 5 . 6 7 . . . ",
|
||||
" . @ 3 8 9 0 4 4 a b . . . c ",
|
||||
" . d e f g h 4 4 4 i j . . k ",
|
||||
" . . 3 l m n 4 3 d o p . . q ",
|
||||
" . . r s t d u v w x . [ . y ",
|
||||
" . z A B C D E F G H . I J . ",
|
||||
" . K L M M N O A P ] Q R . . . . ",
|
||||
" S . T U V W N W N X - / Y . . . . . ",
|
||||
" . Z ` ...+.@.( | #.$.U ! + . . . . . ",
|
||||
" . . , $...%.+.&... .M A *.=.-.. . . . . ",
|
||||
" . . ;.M .+.>.>.,.1 .M A ( &.$.'.. . . . ",
|
||||
" . . ).M ...%.,.Q P .M A ( &.!.~.. . . . ",
|
||||
" . . X V | .....- .| V ) ^ {.!.].. . . . ",
|
||||
" . . + A M | . .- | M A ( N ^.*.& . . . . ",
|
||||
" . . . % ! ^.M M =.V #.P ] {.!./.'.H (.. ",
|
||||
" . . . . . . _.& A /.#.( ] &.$.:.. . . . . <. ",
|
||||
" . [.}.|.. . . . . X !.$.N {.$.1.2.3.4.. . . . 5. ",
|
||||
" . . 6.7.4 8.. . . . 9.&.` &.!.*.0.a.b.c.. . d.e.f.g. ",
|
||||
" . h.i.j.4 k.l.m.. n./ !.!.{ *./.{ o.p.q.r.s.t.u.v.w.. ",
|
||||
" . x.y.4 k.l.z.A.B.. L /./.Q { 1 C.D.. E.F.G.G.H.I.J.K.. ",
|
||||
" . L.k.l.z.A.M.N.. O.P.@._ Q.R.S.. . T.l.r.r.U.V.W.X.. ",
|
||||
" . Y.Z.l.z.A.M.`. +. . . . . . . . . . .+++@+#+$+%+. . ",
|
||||
" . &+*+B.=+-+;+>+. . . . . . . . . . . ,+'+)+!+~+. ",
|
||||
" . . . . . . . . . . . . {+]+^+/+. ",
|
||||
" (+ ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
Loading…
x
Reference in New Issue
Block a user