mirror of
https://git.code.sf.net/p/flwm/flwm
synced 2025-12-12 07:16:57 -05:00
Many changes so it compiles and works with fltk2. Menus are
still a bit screwed up.
This commit is contained in:
240
Frame.C
240
Frame.C
@ -8,6 +8,7 @@
|
||||
#include <FL/fl_draw.H>
|
||||
#include "Rotated.H"
|
||||
|
||||
|
||||
static Atom wm_state = 0;
|
||||
static Atom wm_change_state;
|
||||
static Atom wm_protocols;
|
||||
@ -63,7 +64,7 @@ int dont_set_event_mask = 0; // used by FrameWindow
|
||||
// passed for an already-existing window when the window manager is
|
||||
// starting up. If so we don't want to alter the state, size, or
|
||||
// position. If null than this is a MapRequest of a new window.
|
||||
Frame::Frame(Window window, XWindowAttributes* existing) :
|
||||
Frame::Frame(XWindow window, XWindowAttributes* existing) :
|
||||
Fl_Window(0,0),
|
||||
window_(window),
|
||||
state_flags_(0),
|
||||
@ -223,20 +224,9 @@ Frame::Frame(Window window, XWindowAttributes* existing) :
|
||||
show_hide_buttons();
|
||||
|
||||
if (autoplace && !existing && !(transient_for() && (x() || y()))) {
|
||||
// autoplacement (stupid version for now)
|
||||
x(Root->x()+(Root->w()-w())/2);
|
||||
y(Root->y()+(Root->h()-h())/2);
|
||||
// move it until it does not hide any existing windows:
|
||||
const int delta = TITLE_WIDTH+LEFT;
|
||||
for (Frame* f = next; f; f = f->next) {
|
||||
if (f->x()+delta > x() && f->y()+delta > y() &&
|
||||
f->x()+f->w()-delta < x()+w() && f->y()+f->h()-delta < y()+h()) {
|
||||
x(max(x(),f->x()+delta));
|
||||
y(max(y(),f->y()+delta));
|
||||
f = this;
|
||||
}
|
||||
}
|
||||
place_window();
|
||||
}
|
||||
|
||||
// move window so contents and border are visible:
|
||||
x(force_x_onscreen(x(), w()));
|
||||
y(force_y_onscreen(y(), h()));
|
||||
@ -260,7 +250,8 @@ Frame::Frame(Window window, XWindowAttributes* existing) :
|
||||
sattr.bit_gravity = NorthWestGravity;
|
||||
sattr.override_redirect = 1;
|
||||
sattr.background_pixel = fl_xpixel(FL_GRAY);
|
||||
Fl_X::set_xid(this, XCreateWindow(fl_display, fl_xid(Root),
|
||||
Fl_X::set_xid(this, XCreateWindow(fl_display,
|
||||
RootWindow(fl_display,fl_screen),
|
||||
x(), y(), w(), h(), 0,
|
||||
fl_visual->depth,
|
||||
InputOutput,
|
||||
@ -277,16 +268,141 @@ Frame::Frame(Window window, XWindowAttributes* existing) :
|
||||
sendConfigureNotify(); // many apps expect this even if window size unchanged
|
||||
|
||||
#if CLICK_RAISES || CLICK_TO_TYPE
|
||||
XGrabButton(fl_display, AnyButton, AnyModifier, window, False,
|
||||
ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);
|
||||
if (!dont_set_event_mask)
|
||||
XGrabButton(fl_display, AnyButton, AnyModifier, window, False,
|
||||
ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);
|
||||
#endif
|
||||
|
||||
if (state_ == NORMAL) {
|
||||
XMapWindow(fl_display, fl_xid(this));
|
||||
if (!existing) activate_if_transient();
|
||||
}
|
||||
set_visible();
|
||||
}
|
||||
|
||||
#if SMART_PLACEMENT
|
||||
// Helper functions for "smart" window placement.
|
||||
int overlap1(int p1, int l1, int p2, int l2) {
|
||||
int ret = 0;
|
||||
if(p1 <= p2 && p2 <= p1 + l1) {
|
||||
ret = min(p1 + l1 - p2, l2);
|
||||
} else if (p2 <= p1 && p1 <= p2 + l2) {
|
||||
ret = min(p2 + l2 - p1, l1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
|
||||
return (overlap1(x1, w1, x2, w2) * overlap1(y1, h1, y2, h2));
|
||||
}
|
||||
|
||||
// Compute the overlap with existing windows.
|
||||
// For normal windows the overlapping area is taken into account plus a
|
||||
// constant value for every overlapping window.
|
||||
// The active window counts twice.
|
||||
// For iconic windows half the overlapping area is taken into account.
|
||||
int getOverlap(int x, int y, int w, int h, Frame *first, Frame *self) {
|
||||
int ret = 0;
|
||||
short state;
|
||||
for (Frame* f = first; f; f = f->next) {
|
||||
if (f != self) {
|
||||
state = f->state();
|
||||
if (state == NORMAL || state == ICONIC) {
|
||||
int o = overlap(x, y, w, h, f->x(), f->y(), f->w(), f->h());
|
||||
if (state == NORMAL) {
|
||||
ret = ret + o + (o>0?40000:0) + (o * f->active());
|
||||
} else if (state == ICONIC) {
|
||||
ret = ret + o/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// autoplacement (brute force version for now)
|
||||
void Frame::place_window() {
|
||||
int min_overlap = -1;
|
||||
int tmp_x, tmp_y, tmp_o;
|
||||
int best_x = 0;
|
||||
int best_y = 0;
|
||||
int _w = w();
|
||||
int _h = h();
|
||||
int max_x = Root->x() + Root->w();
|
||||
int max_y = Root->y() + Root->h();
|
||||
|
||||
Frame *f1 = Frame::first;
|
||||
for(int i=0;; i++) {
|
||||
if (i==0) {
|
||||
tmp_x = 0;
|
||||
} else if (i==1) {
|
||||
tmp_x = max_x - _w;
|
||||
} else {
|
||||
if (f1 == this) {
|
||||
f1 = f1->next;
|
||||
}
|
||||
if (!f1) {
|
||||
break;
|
||||
}
|
||||
tmp_x = f1->x() + f1->w();
|
||||
f1 = f1->next;
|
||||
}
|
||||
Frame *f2 = Frame::first;
|
||||
for(int j=0;; j++) {
|
||||
if (j==0) {
|
||||
tmp_y = 0;
|
||||
} else if (j==1) {
|
||||
tmp_y = max_y - _h;
|
||||
} else {
|
||||
if (f2 == this) {
|
||||
f2 = f2->next;
|
||||
}
|
||||
if (!f2) {
|
||||
break;
|
||||
}
|
||||
tmp_y = f2->y() + f2->h();
|
||||
f2 = f2->next;
|
||||
}
|
||||
|
||||
if ((tmp_x + _w <= max_x) && (tmp_y + _h <= max_y)) {
|
||||
tmp_o = getOverlap(tmp_x, tmp_y, _w, _h, Frame::first, this);
|
||||
if(tmp_o < min_overlap || min_overlap < 0) {
|
||||
best_x = tmp_x;
|
||||
best_y = tmp_y;
|
||||
min_overlap = tmp_o;
|
||||
if (min_overlap == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (min_overlap == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
x(best_x);
|
||||
y(best_y);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// autoplacement (stupid version for now)
|
||||
void Frame::place_window() {
|
||||
x(Root->x()+(Root->w()-w())/2);
|
||||
y(Root->y()+(Root->h()-h())/2);
|
||||
// move it until it does not hide any existing windows:
|
||||
const int delta = TITLE_WIDTH+LEFT;
|
||||
for (Frame* f = next; f; f = f->next) {
|
||||
if (f->x()+delta > x() && f->y()+delta > y() &&
|
||||
f->x()+f->w()-delta < x()+w() && f->y()+f->h()-delta < y()+h()) {
|
||||
x(max(x(),f->x()+delta));
|
||||
y(max(y(),f->y()+delta));
|
||||
f = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// modify the passed X & W to a legal horizontal window position
|
||||
int Frame::force_x_onscreen(int X, int W) {
|
||||
// force all except the black border on-screen:
|
||||
@ -333,10 +449,12 @@ Frame::~Frame() {
|
||||
// a legal state value to this location:
|
||||
state_ = UNMAPPED;
|
||||
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
// fix fltk bug:
|
||||
fl_xfocus = 0;
|
||||
fl_xmousewin = 0;
|
||||
Fl::focus_ = 0;
|
||||
#endif
|
||||
|
||||
// remove any pointers to this:
|
||||
Frame** cp; for (cp = &first; *cp; cp = &((*cp)->next))
|
||||
@ -554,7 +672,7 @@ int Frame::getMotifHints() {
|
||||
// see if they set "input hint" to non-zero:
|
||||
// prop[3] should be nonzero but the only example of this I have
|
||||
// found is Netscape 3.0 and it sets it to zero...
|
||||
if (!shown() && (prop[0]&4) /*&& prop[3]*/) set_flag(MODAL);
|
||||
if (!shown() && (prop[0]&4) /*&& prop[3]*/) set_flag(::MODAL);
|
||||
|
||||
// see if it is forcing the iconize button back on. This makes
|
||||
// transient_for act like group instead...
|
||||
@ -578,7 +696,7 @@ void Frame::getColormaps(void) {
|
||||
delete[] window_Colormaps;
|
||||
}
|
||||
int n;
|
||||
Window* cw = (Window*)getProperty(wm_colormap_windows, XA_WINDOW, &n);
|
||||
XWindow* cw = (XWindow*)getProperty(wm_colormap_windows, XA_WINDOW, &n);
|
||||
if (cw) {
|
||||
colormapWinCount = n;
|
||||
colormapWindows = cw;
|
||||
@ -644,7 +762,7 @@ int Frame::activate_if_transient() {
|
||||
int Frame::activate(int warp) {
|
||||
// see if a modal & newer window is up:
|
||||
for (Frame* c = first; c && c != this; c = c->next)
|
||||
if (c->flag(MODAL) && c->transient_for() == this)
|
||||
if (c->flag(::MODAL) && c->transient_for() == this)
|
||||
if (c->activate(warp)) return 1;
|
||||
// ignore invisible windows:
|
||||
if (state() != NORMAL || w() <= dwidth) return 0;
|
||||
@ -670,14 +788,14 @@ int Frame::activate(int warp) {
|
||||
if (active_ != this) {
|
||||
if (active_) active_->deactivate();
|
||||
active_ = this;
|
||||
#if defined(ACTIVE_COLOR)
|
||||
#ifdef ACTIVE_COLOR
|
||||
XSetWindowAttributes a;
|
||||
a.background_pixel = fl_xpixel(FL_SELECTION_COLOR);
|
||||
XChangeWindowAttributes(fl_display, fl_xid(this), CWBackPixel, &a);
|
||||
labelcolor(contrast(FL_BLACK, FL_SELECTION_COLOR));
|
||||
XClearArea(fl_display, fl_xid(this), 2, 2, w()-4, h()-4, 1);
|
||||
#else
|
||||
#if defined(SHOW_CLOCK)
|
||||
#ifdef SHOW_CLOCK
|
||||
redraw();
|
||||
#endif
|
||||
#endif
|
||||
@ -690,14 +808,14 @@ int Frame::activate(int warp) {
|
||||
// this private function should only be called by constructor and if
|
||||
// the window is active():
|
||||
void Frame::deactivate() {
|
||||
#if defined(ACTIVE_COLOR)
|
||||
#ifdef ACTIVE_COLOR
|
||||
XSetWindowAttributes a;
|
||||
a.background_pixel = fl_xpixel(FL_GRAY);
|
||||
XChangeWindowAttributes(fl_display, fl_xid(this), CWBackPixel, &a);
|
||||
labelcolor(FL_BLACK);
|
||||
XClearArea(fl_display, fl_xid(this), 2, 2, w()-4, h()-4, 1);
|
||||
#else
|
||||
#if defined(SHOW_CLOCK)
|
||||
#ifdef SHOW_CLOCK
|
||||
redraw();
|
||||
#endif
|
||||
#endif
|
||||
@ -737,9 +855,9 @@ void Frame::state(short newstate) {
|
||||
switch (newstate) {
|
||||
case UNMAPPED:
|
||||
throw_focus();
|
||||
set_state_flag(IGNORE_UNMAP);
|
||||
XUnmapWindow(fl_display, fl_xid(this));
|
||||
XUnmapWindow(fl_display, window_);
|
||||
//set_state_flag(IGNORE_UNMAP);
|
||||
//XUnmapWindow(fl_display, window_);
|
||||
XRemoveFromSaveSet(fl_display, window_);
|
||||
break;
|
||||
case NORMAL:
|
||||
@ -753,9 +871,9 @@ void Frame::state(short newstate) {
|
||||
XAddToSaveSet(fl_display, window_);
|
||||
} else if (oldstate == NORMAL) {
|
||||
throw_focus();
|
||||
set_state_flag(IGNORE_UNMAP);
|
||||
XUnmapWindow(fl_display, fl_xid(this));
|
||||
XUnmapWindow(fl_display, window_);
|
||||
//set_state_flag(IGNORE_UNMAP);
|
||||
//XUnmapWindow(fl_display, window_);
|
||||
} else {
|
||||
return; // don't setStateProperty IconicState multiple times
|
||||
}
|
||||
@ -908,7 +1026,7 @@ void Frame::set_size(int nx, int ny, int nw, int nh, int warp) {
|
||||
int old_label_y = label_y;
|
||||
int old_label_h = label_h;
|
||||
h(nh); show_hide_buttons();
|
||||
#ifdef SHOW_CLOCK
|
||||
#if 1 //def SHOW_CLOCK
|
||||
int t = label_y + 3; // we have to clear the entire label area
|
||||
#else
|
||||
int t = nh;
|
||||
@ -1075,6 +1193,8 @@ void Frame::show_hide_buttons() {
|
||||
|
||||
// make sure fltk does not try to set the window size:
|
||||
void Frame::resize(int, int, int, int) {}
|
||||
// For fltk2.0:
|
||||
void Frame::layout() {layout_damage(0);}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1110,19 +1230,27 @@ void Frame::save_protocol() {
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Drawing code:
|
||||
#if FL_MAJOR_VERSION>1
|
||||
# include <fltk/Box.h>
|
||||
#endif
|
||||
|
||||
void Frame::draw() {
|
||||
if (flag(NO_BORDER)) return;
|
||||
if (!flag(THIN_BORDER)) Fl_Window::draw();
|
||||
if (damage() != FL_DAMAGE_CHILD) {
|
||||
#if ACTIVE_COLOR
|
||||
#ifdef ACTIVE_COLOR
|
||||
fl_frame2(active() ? "AAAAJJWW" : "AAAAJJWWNNTT",0,0,w(),h());
|
||||
if (active()) {
|
||||
fl_color(FL_GRAY_RAMP+('N'-'A'));
|
||||
fl_xyline(2, h()-3, w()-3, 2);
|
||||
}
|
||||
#else
|
||||
# if FL_MAJOR_VERSION>1
|
||||
static fltk::FrameBox framebox(0,"AAAAJJWWNNTT");
|
||||
framebox.draw(0,0,w(),h(),style(),fltk::INVISIBLE); // INVISIBLE = draw edge only
|
||||
# else
|
||||
fl_frame("AAAAWWJJTTNN",0,0,w(),h());
|
||||
# endif
|
||||
#endif
|
||||
if (!flag(THIN_BORDER) && label_h > 3) {
|
||||
#ifdef SHOW_CLOCK
|
||||
@ -1168,39 +1296,48 @@ void Frame::redraw_clock() {
|
||||
#endif
|
||||
|
||||
void FrameButton::draw() {
|
||||
#if FL_MAJOR_VERSION>1
|
||||
const int x = 0;
|
||||
const int y = 0;
|
||||
FL_UP_BOX->draw(0,0,w(),h(),style(),
|
||||
value() ? (fltk::INVISIBLE|fltk::VALUE) : fltk::INVISIBLE);
|
||||
#else
|
||||
const int x = this->x();
|
||||
const int y = this->y();
|
||||
Fl_Widget::draw_box(value() ? FL_DOWN_FRAME : FL_UP_FRAME, FL_GRAY);
|
||||
#endif
|
||||
fl_color(parent()->labelcolor());
|
||||
switch (label()[0]) {
|
||||
case 'W':
|
||||
#if MINIMIZE_ARROW
|
||||
fl_line (x()+2,y()+(h())/2,x()+w()-4,y()+h()/2);
|
||||
fl_line (x()+2,y()+(h())/2,x()+2+4,y()+h()/2+4);
|
||||
fl_line (x()+2,y()+(h())/2,x()+2+4,y()+h()/2-4);
|
||||
fl_line (x+2,y+(h())/2,x+w()-4,y+h()/2);
|
||||
fl_line (x+2,y+(h())/2,x+2+4,y+h()/2+4);
|
||||
fl_line (x+2,y+(h())/2,x+2+4,y+h()/2-4);
|
||||
#else
|
||||
fl_rect(x()+(h()-7)/2,y()+3,2,h()-6);
|
||||
fl_rect(x+(h()-7)/2,y+3,2,h()-6);
|
||||
#endif
|
||||
return;
|
||||
case 'w':
|
||||
fl_rect(x()+2,y()+(h()-7)/2,w()-4,7);
|
||||
fl_rect(x+2,y+(h()-7)/2,w()-4,7);
|
||||
return;
|
||||
case 'h':
|
||||
fl_rect(x()+(h()-7)/2,y()+2,7,h()-4);
|
||||
fl_rect(x+(h()-7)/2,y+2,7,h()-4);
|
||||
return;
|
||||
case 'X':
|
||||
#if CLOSE_X
|
||||
fl_line(x()+2,y()+3,x()+w()-5,y()+h()-4);
|
||||
fl_line(x()+3,y()+3,x()+w()-4,y()+h()-4);
|
||||
fl_line(x()+2,y()+h()-4,x()+w()-5,y()+3);
|
||||
fl_line(x()+3,y()+h()-4,x()+w()-4,y()+3);
|
||||
fl_line(x+2,y+3,x+w()-5,y+h()-4);
|
||||
fl_line(x+3,y+3,x+w()-4,y+h()-4);
|
||||
fl_line(x+2,y+h()-4,x+w()-5,y+3);
|
||||
fl_line(x+3,y+h()-4,x+w()-4,y+3);
|
||||
#endif
|
||||
#if CLOSE_HITTITE_LIGHTNING
|
||||
fl_arc(x()+3,y()+3,w()-6,h()-6,0,360);
|
||||
fl_line(x()+7,y()+3, x()+7,y()+11);
|
||||
fl_arc(x+3,y+3,w()-6,h()-6,0,360);
|
||||
fl_line(x+7,y+3, x+7,y+11);
|
||||
#endif
|
||||
return;
|
||||
case 'i':
|
||||
#if ICONIZE_BOX
|
||||
fl_rect(x()+w()/2-1,y()+h()/2-1,3,3);
|
||||
fl_rect(x+w()/2-1,y+h()/2-1,3,3);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@ -1324,7 +1461,11 @@ void Frame::set_cursor(int r) {
|
||||
if (this != previous_frame || c != previous_cursor) {
|
||||
previous_frame = this;
|
||||
previous_cursor = c;
|
||||
#if FL_MAJOR_VERSION>1
|
||||
cursor(c);
|
||||
#else
|
||||
cursor(c, CURSOR_FG_SLOT, CURSOR_BG_SLOT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1577,9 +1718,10 @@ int Frame::handle(const XEvent* ei) {
|
||||
|
||||
case UnmapNotify: {
|
||||
const XUnmapEvent* e = &(ei->xunmap);
|
||||
if (e->from_configure);
|
||||
else if (state_flags_&IGNORE_UNMAP) clear_state_flag(IGNORE_UNMAP);
|
||||
else state(UNMAPPED);
|
||||
if (e->window == window_ && !e->from_configure) {
|
||||
if (state_flags_&IGNORE_UNMAP) clear_state_flag(IGNORE_UNMAP);
|
||||
else state(UNMAPPED);
|
||||
}
|
||||
return 1;}
|
||||
|
||||
case DestroyNotify: {
|
||||
@ -1676,7 +1818,7 @@ void* Frame::getProperty(Atom a, Atom type, int* np) const {
|
||||
return ::getProperty(window_, a, type, np);
|
||||
}
|
||||
|
||||
void* getProperty(Window w, Atom a, Atom type, int* np) {
|
||||
void* getProperty(XWindow w, Atom a, Atom type, int* np) {
|
||||
Atom realType;
|
||||
int format;
|
||||
unsigned long n, extra;
|
||||
@ -1696,7 +1838,7 @@ int Frame::getIntProperty(Atom a, Atom type, int deflt) const {
|
||||
return ::getIntProperty(window_, a, type, deflt);
|
||||
}
|
||||
|
||||
int getIntProperty(Window w, Atom a, Atom type, int deflt) {
|
||||
int getIntProperty(XWindow w, Atom a, Atom type, int deflt) {
|
||||
void* prop = getProperty(w, a, type);
|
||||
if (!prop) return deflt;
|
||||
int r = int(*(long*)prop);
|
||||
@ -1704,7 +1846,7 @@ int getIntProperty(Window w, Atom a, Atom type, int deflt) {
|
||||
return r;
|
||||
}
|
||||
|
||||
void setProperty(Window w, Atom a, Atom type, int v) {
|
||||
void setProperty(XWindow w, Atom a, Atom type, int v) {
|
||||
long prop = v;
|
||||
XChangeProperty(fl_display, w, a, type, 32, PropModeReplace, (uchar*)&prop,1);
|
||||
}
|
||||
|
||||
21
Frame.H
21
Frame.H
@ -9,6 +9,9 @@
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/x.H>
|
||||
#if FL_MAJOR_VERSION<2
|
||||
# define XWindow Window
|
||||
#endif
|
||||
|
||||
// The state is an enumeration of reasons why the window may be invisible.
|
||||
// Only if it is NORMAL is the window visible.
|
||||
@ -58,7 +61,7 @@ class Desktop;
|
||||
|
||||
class Frame : public Fl_Window {
|
||||
|
||||
Window window_;
|
||||
XWindow window_;
|
||||
|
||||
short state_; // X server state: iconic, withdrawn, normal
|
||||
short state_flags_; // above state flags
|
||||
@ -79,14 +82,14 @@ class Frame : public Fl_Window {
|
||||
int label_y, label_h; // location of label
|
||||
int label_w; // measured width of printed label
|
||||
|
||||
Window transient_for_xid; // value from X
|
||||
XWindow 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;
|
||||
XWindow *colormapWindows;
|
||||
Colormap *window_Colormaps; // their colormaps
|
||||
|
||||
Desktop* desktop_;
|
||||
@ -101,6 +104,7 @@ class Frame : public Fl_Window {
|
||||
int maximize_height();
|
||||
int force_x_onscreen(int X, int W);
|
||||
int force_y_onscreen(int Y, int H);
|
||||
void place_window();
|
||||
|
||||
void sendMessage(Atom, Atom) const;
|
||||
void sendConfigureNotify() const;
|
||||
@ -122,6 +126,7 @@ class Frame : public Fl_Window {
|
||||
|
||||
void set_size(int,int,int,int, int warp=0);
|
||||
void resize(int,int,int,int);
|
||||
void layout();
|
||||
void show_hide_buttons();
|
||||
|
||||
int handle(int); // handle fltk events
|
||||
@ -151,10 +156,10 @@ public:
|
||||
static Frame* first;
|
||||
Frame* next; // stacking order, top to bottom
|
||||
|
||||
Frame(Window, XWindowAttributes* = 0);
|
||||
Frame(XWindow, XWindowAttributes* = 0);
|
||||
~Frame();
|
||||
|
||||
Window window() const {return window_;}
|
||||
XWindow window() const {return window_;}
|
||||
Frame* transient_for() const {return transient_for_;}
|
||||
int is_transient_for(const Frame*) const;
|
||||
|
||||
@ -185,8 +190,8 @@ public:
|
||||
};
|
||||
|
||||
// handy wrappers for those ugly X routines:
|
||||
void* getProperty(Window, Atom, Atom = AnyPropertyType, int* length = 0);
|
||||
int getIntProperty(Window, Atom, Atom = AnyPropertyType, int deflt = 0);
|
||||
void setProperty(Window, Atom, Atom, int);
|
||||
void* getProperty(XWindow, Atom, Atom = AnyPropertyType, int* length = 0);
|
||||
int getIntProperty(XWindow, Atom, Atom = AnyPropertyType, int deflt = 0);
|
||||
void setProperty(XWindow, Atom, Atom, int);
|
||||
|
||||
#endif
|
||||
|
||||
@ -165,7 +165,7 @@ int Handle_Hotkey() {
|
||||
extern Fl_Window* Root;
|
||||
|
||||
void Grab_Hotkeys() {
|
||||
Window root = fl_xid(Root);
|
||||
XWindow root = fl_xid(Root);
|
||||
for (int i = 0; keybindings[i].key; i++) {
|
||||
int k = keybindings[i].key;
|
||||
int keycode = XKeysymToKeycode(fl_display, k & 0xFFFF);
|
||||
|
||||
26
Menu.C
26
Menu.C
@ -61,6 +61,7 @@ move_frame_callback(Fl_Widget*, void*d)
|
||||
|
||||
extern Fl_Window* Root;
|
||||
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
static void
|
||||
frame_label_draw(const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
|
||||
{
|
||||
@ -131,6 +132,8 @@ label_measure(const Fl_Label* o, int& W, int& H)
|
||||
#define FRAME_LABEL FL_FREE_LABELTYPE
|
||||
#define TEXT_LABEL Fl_Labeltype(FL_FREE_LABELTYPE+1)
|
||||
|
||||
#endif // FL_MAJOR_VERSION < 2
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static void
|
||||
@ -155,7 +158,7 @@ delete_desktop_cb(Fl_Widget*, void* v)
|
||||
|
||||
#if ASK_FOR_NEW_DESKTOP_NAME
|
||||
|
||||
static Fl_Input* new_desktop_input;
|
||||
static Fl_Input* new_desktop_input = 0;
|
||||
|
||||
static void
|
||||
new_desktop_ok_cb(Fl_Widget* w, void*)
|
||||
@ -205,6 +208,7 @@ new_desktop_cb(Fl_Widget*, void*)
|
||||
static void
|
||||
exit_cb(Fl_Widget*, void*)
|
||||
{
|
||||
printf("exit_cb\n");
|
||||
Frame::save_protocol();
|
||||
exit(0);
|
||||
}
|
||||
@ -212,7 +216,7 @@ exit_cb(Fl_Widget*, void*)
|
||||
static void
|
||||
logout_cb(Fl_Widget*, void*)
|
||||
{
|
||||
static FrameWindow* w;
|
||||
static FrameWindow* w = 0;
|
||||
if (!w) {
|
||||
w = new FrameWindow(190,90);
|
||||
Fl_Box* l = new Fl_Box(0, 0, 190, 60, "Really log out?");
|
||||
@ -419,8 +423,10 @@ ShowTabMenu(int tab)
|
||||
static char beenhere;
|
||||
if (!beenhere) {
|
||||
beenhere = 1;
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
Fl::set_labeltype(FRAME_LABEL, frame_label_draw, frame_label_measure);
|
||||
Fl::set_labeltype(TEXT_LABEL, label_draw, label_measure);
|
||||
#endif
|
||||
if (exit_flag) {
|
||||
Fl_Menu_Item* m = other_menu_items+num_other_items-2;
|
||||
m->label("Exit");
|
||||
@ -507,8 +513,12 @@ ShowTabMenu(int tab)
|
||||
#endif
|
||||
for (c = Frame::first; c; c = c->next) {
|
||||
if (c->state() == UNMAPPED || c->transient_for()) continue;
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
init(menu[n],(char*)c);
|
||||
menu[n].labeltype(FRAME_LABEL);
|
||||
#else
|
||||
init(menu[n],c->label());
|
||||
#endif
|
||||
menu[n].callback(frame_callback, c);
|
||||
if (is_active_frame(c)) preset = menu+n;
|
||||
n++;
|
||||
@ -537,7 +547,12 @@ ShowTabMenu(int tab)
|
||||
if (c->state() == UNMAPPED || c->transient_for()) continue;
|
||||
if (c->desktop() == d || !c->desktop() && d == Desktop::current()) {
|
||||
init(menu[n],(char*)c);
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
init(menu[n],(char*)c);
|
||||
menu[n].labeltype(FRAME_LABEL);
|
||||
#else
|
||||
init(menu[n],c->label());
|
||||
#endif
|
||||
menu[n].callback(d == Desktop::current() ?
|
||||
frame_callback : move_frame_callback, c);
|
||||
if (d == Desktop::current() && is_active_frame(c)) preset = menu+n;
|
||||
@ -581,12 +596,13 @@ ShowTabMenu(int tab)
|
||||
cmd = wmxlist[i];
|
||||
cmd += strspn(cmd, "/")-1;
|
||||
init(menu[n], cmd+pathlen[level]);
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
#if DESKTOPS
|
||||
if (one_desktop)
|
||||
#endif
|
||||
if (!level)
|
||||
menu[n].labeltype(TEXT_LABEL);
|
||||
|
||||
#endif
|
||||
int nextlev = (i==num_wmx-1)?0:strspn(wmxlist[i+1], "/")-1;
|
||||
if (nextlev < level) {
|
||||
menu[n].callback(spawn_cb, cmd);
|
||||
@ -613,15 +629,19 @@ ShowTabMenu(int tab)
|
||||
#endif
|
||||
#endif
|
||||
memcpy(menu+n, other_menu_items, sizeof(other_menu_items));
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
#if DESKTOPS
|
||||
if (one_desktop)
|
||||
#endif
|
||||
// fix the menus items so they are indented to align with window names:
|
||||
while (menu[n].label()) menu[n++].labeltype(TEXT_LABEL);
|
||||
#endif
|
||||
|
||||
const Fl_Menu_Item* picked =
|
||||
menu->popup(Fl::event_x(), Fl::event_y(), 0, preset);
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
if (picked && picked->callback()) picked->do_callback(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShowMenu() {ShowTabMenu(0);}
|
||||
|
||||
37
Rotated.C
37
Rotated.C
@ -27,6 +27,9 @@
|
||||
/* ********************************************************************** */
|
||||
|
||||
#include <FL/x.H>
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
# define XWindow Window
|
||||
#endif
|
||||
#include <FL/fl_draw.H>
|
||||
#include "Rotated.H"
|
||||
#include <stdlib.h>
|
||||
@ -67,7 +70,7 @@ XRotLoadFont(Display *dpy, XFontStruct* fontstruct, int dir)
|
||||
char val;
|
||||
XImage *I1, *I2;
|
||||
Pixmap canvas;
|
||||
Window root;
|
||||
XWindow root;
|
||||
int screen;
|
||||
GC font_gc;
|
||||
char text[3];/*, errstr[300];*/
|
||||
@ -235,9 +238,9 @@ XRotLoadFont(Display *dpy, XFontStruct* fontstruct, int dir)
|
||||
}
|
||||
|
||||
for (ichar = 0; ichar < min_char; ichar++)
|
||||
rotfont->per_char[ichar] = rotfont->per_char['?'];
|
||||
rotfont->per_char[ichar] = rotfont->per_char[int('?')];
|
||||
for (ichar = max_char+1; ichar < 256; ichar++)
|
||||
rotfont->per_char[ichar] = rotfont->per_char['?'];
|
||||
rotfont->per_char[ichar] = rotfont->per_char[int('?')];
|
||||
|
||||
/* free pixmap and GC ... */
|
||||
XFreePixmap(dpy, canvas);
|
||||
@ -351,23 +354,25 @@ static int XRotTextWidth(XRotFontStruct *rotfont, const char *str, int len)
|
||||
|
||||
static XRotFontStruct* font;
|
||||
|
||||
void draw_rotated(const char* text, int n, int x, int y, int angle) {
|
||||
if (!text || !*text) return;
|
||||
static void setrotfont(int angle) {
|
||||
/* make angle positive ... */
|
||||
if (angle < 0) do angle += 360; while (angle < 0);
|
||||
/* get nearest vertical or horizontal direction ... */
|
||||
int dir = ((angle+45)/90)%4;
|
||||
|
||||
if (font && font->xfontstruct == fl_xfont && font->dir == dir) {
|
||||
;
|
||||
} else {
|
||||
if (font) XRotUnloadFont(fl_display, font);
|
||||
font = XRotLoadFont(fl_display, fl_xfont, dir);
|
||||
if (font) {
|
||||
if (font->xfontstruct == fl_xfont && font->dir == dir) return;
|
||||
XRotUnloadFont(fl_display, font);
|
||||
}
|
||||
font = XRotLoadFont(fl_display, fl_xfont, dir);
|
||||
}
|
||||
|
||||
void draw_rotated(const char* text, int n, int x, int y, int angle) {
|
||||
if (!text || !*text) return;
|
||||
setrotfont(angle);
|
||||
XRotDrawString(fl_display, font, fl_window, fl_gc, x, y, text, n);
|
||||
}
|
||||
|
||||
#ifndef FLWM
|
||||
#if !defined(FLWM) || FL_MAJOR_VERSION>=2
|
||||
void draw_rotated(const char* text, int x, int y, int angle) {
|
||||
if (!text || !*text) return;
|
||||
draw_rotated(text, strlen(text), x, y, angle);
|
||||
@ -384,12 +389,20 @@ void draw_rotated90(
|
||||
if (!str || !*str) return;
|
||||
if (w && h && !fl_not_clipped(x, y, w, h)) return;
|
||||
if (align & FL_ALIGN_CLIP) fl_clip(x, y, w, h);
|
||||
#if FL_MAJOR_VERSION>1
|
||||
setrotfont(90);
|
||||
int a = font->xfontstruct->ascent;
|
||||
int d = font->xfontstruct->descent;
|
||||
XRotDrawString(fl_display, font, fl_window, fl_gc,
|
||||
x+(w+a-d+1)/2, y+h, str, strlen(str));
|
||||
#else
|
||||
int a1 = align&(-16);
|
||||
if (align & FL_ALIGN_LEFT) a1 |= FL_ALIGN_TOP;
|
||||
if (align & FL_ALIGN_RIGHT) a1 |= FL_ALIGN_BOTTOM;
|
||||
if (align & FL_ALIGN_TOP) a1 |= FL_ALIGN_RIGHT;
|
||||
if (align & FL_ALIGN_BOTTOM) a1 |= FL_ALIGN_LEFT;
|
||||
fl_draw(str, -(y+h), x, h, w, (Fl_Align)a1, draw_rot90);
|
||||
#endif
|
||||
if (align & FL_ALIGN_CLIP) fl_pop_clip();
|
||||
}
|
||||
|
||||
|
||||
6
config.h
6
config.h
@ -25,6 +25,12 @@
|
||||
// nothing is done if this is not defined:
|
||||
//#define AUTO_RAISE 0.5
|
||||
|
||||
// Perform "smart" autoplacement.
|
||||
// New windows are put at positions where they cover as few existing windows
|
||||
// as possible. A brute force algorithm is used, so it consumes quite a bit
|
||||
// of CPU time.
|
||||
#define SMART_PLACEMENT 1
|
||||
|
||||
// set this to zero to remove the multiple-desktop code. This will
|
||||
// make flwm about 20K smaller
|
||||
#define DESKTOPS 1
|
||||
|
||||
63
main.C
63
main.C
@ -69,7 +69,7 @@ extern void click_raise(Frame*);
|
||||
// fltk calls this for any events it does not understand:
|
||||
static int flwm_event_handler(int e) {
|
||||
if (!e) { // XEvent that fltk did not understand.
|
||||
Window window = fl_xevent->xany.window;
|
||||
XWindow window = fl_xevent->xany.window;
|
||||
// unfortunately most of the redirect events put the interesting
|
||||
// window id in a different place:
|
||||
switch (fl_xevent->type) {
|
||||
@ -114,7 +114,11 @@ static int flwm_event_handler(int e) {
|
||||
XKeycodeToKeysym(fl_display, fl_xevent->xkey.keycode, 0);
|
||||
if (keysym == FL_Alt_L || keysym == FL_Alt_R) {
|
||||
Fl::e_keysym = FL_Enter;
|
||||
#if FL_MAJOR_VERSION>1
|
||||
return Fl::modal()->handle(FL_KEYBOARD);
|
||||
#else
|
||||
return Fl::grab()->handle(FL_KEYBOARD);
|
||||
#endif
|
||||
}
|
||||
return 0;}
|
||||
}
|
||||
@ -189,28 +193,26 @@ void flwm_clock_alarm_off(int) {
|
||||
#endif
|
||||
|
||||
static const char* cfg, *cbg;
|
||||
#if FL_MAJOR_VERSION>1
|
||||
static fltk::Cursor* cursor = FL_CURSOR_ARROW;
|
||||
extern FL_API fltk::Color fl_cursor_fg;
|
||||
extern FL_API fltk::Color fl_cursor_bg;
|
||||
#else
|
||||
static int cursor = FL_CURSOR_ARROW;
|
||||
|
||||
static void color_setup(Fl_Color slot, const char* arg, ulong value) {
|
||||
if (arg) {
|
||||
XColor x;
|
||||
if (XParseColor(fl_display, fl_colormap, arg, &x))
|
||||
value = ((x.red>>8)<<24)|((x.green>>8)<<16)|((x.blue));
|
||||
}
|
||||
Fl::set_color(slot, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void initialize() {
|
||||
|
||||
Display* d = fl_display;
|
||||
|
||||
#ifdef TEST
|
||||
Window w = XCreateSimpleWindow(d, root,
|
||||
XWindow w = XCreateSimpleWindow(d, RootWindow(d, fl_screen),
|
||||
100, 100, 200, 300, 10,
|
||||
BlackPixel(fl_display, 0),
|
||||
// WhitePixel(fl_display, 0));
|
||||
0x1234);
|
||||
Frame* frame = new Frame(w);
|
||||
frame->label("flwm test window");
|
||||
XSelectInput(d, w,
|
||||
ExposureMask | StructureNotifyMask |
|
||||
KeyPressMask | KeyReleaseMask | FocusChangeMask |
|
||||
@ -230,9 +232,11 @@ static void initialize() {
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
KeyPressMask | KeyReleaseMask | KeymapStateMask);
|
||||
color_setup(CURSOR_FG_SLOT, cfg, CURSOR_FG_COLOR<<8);
|
||||
color_setup(CURSOR_BG_SLOT, cbg, CURSOR_BG_COLOR<<8);
|
||||
#if FL_MAJOR_VERSION>1
|
||||
Root->cursor(cursor);
|
||||
#else
|
||||
Root->cursor((Fl_Cursor)cursor, CURSOR_FG_SLOT, CURSOR_BG_SLOT);
|
||||
#endif
|
||||
|
||||
#ifdef TITLE_FONT
|
||||
Fl::set_font(TITLE_FONT_SLOT, TITLE_FONT);
|
||||
@ -247,7 +251,7 @@ static void initialize() {
|
||||
// Gnome crap:
|
||||
// First create a window that can be watched to see if wm dies:
|
||||
Atom a = XInternAtom(d, "_WIN_SUPPORTING_WM_CHECK", False);
|
||||
Window win = XCreateSimpleWindow(d, fl_xid(Root), -200, -200, 5, 5, 0, 0, 0);
|
||||
XWindow win = XCreateSimpleWindow(d, fl_xid(Root), -200, -200, 5, 5, 0, 0, 0);
|
||||
CARD32 val = win;
|
||||
XChangeProperty(d, fl_xid(Root), a, XA_CARDINAL, 32, PropModeReplace, (uchar*)&val, 1);
|
||||
XChangeProperty(d, win, a, XA_CARDINAL, 32, PropModeReplace, (uchar*)&val, 1);
|
||||
@ -287,7 +291,7 @@ static void initialize() {
|
||||
|
||||
// find all the windows and create a Frame for each:
|
||||
unsigned int n;
|
||||
Window w1, w2, *wins;
|
||||
XWindow w1, w2, *wins;
|
||||
XWindowAttributes attr;
|
||||
XQueryTree(d, fl_xid(Root), &w1, &w2, &wins, &n);
|
||||
for (i = 0; i < n; ++i) {
|
||||
@ -328,8 +332,10 @@ int arg(int argc, char **argv, int &i) {
|
||||
cfg = v;
|
||||
} else if (!strcmp(s, "cbg")) {
|
||||
cbg = v;
|
||||
#if FL_MAJOR_VERSION < 2
|
||||
} else if (*s == 'c') {
|
||||
cursor = atoi(v);
|
||||
#endif
|
||||
} else if (*s == 'v') {
|
||||
int visid = atoi(v);
|
||||
fl_open_display();
|
||||
@ -350,6 +356,17 @@ int arg(int argc, char **argv, int &i) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
#if FL_MAJOR_VERSION<2
|
||||
static void color_setup(Fl_Color slot, const char* arg, ulong value) {
|
||||
if (arg) {
|
||||
XColor x;
|
||||
if (XParseColor(fl_display, fl_colormap, arg, &x))
|
||||
value = ((x.red>>8)<<24)|((x.green>>8)<<16)|((x.blue));
|
||||
}
|
||||
Fl::set_color(slot, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
program_name = filename_name(argv[0]);
|
||||
int i; if (Fl::args(argc, argv, i, arg) < argc) Fl::error(
|
||||
@ -369,8 +386,22 @@ int main(int argc, char** argv) {
|
||||
#ifndef FL_NORMAL_SIZE // detect new versions of fltk where this is a variable
|
||||
FL_NORMAL_SIZE = 12;
|
||||
#endif
|
||||
#if FL_MAJOR_VERSION>1
|
||||
if (cfg) fl_cursor_fg = fltk::color(cfg);
|
||||
if (cbg) fl_cursor_bg = fltk::color(cbg);
|
||||
#else
|
||||
fl_open_display();
|
||||
color_setup(CURSOR_FG_SLOT, cfg, CURSOR_FG_COLOR<<8);
|
||||
color_setup(CURSOR_BG_SLOT, cbg, CURSOR_BG_COLOR<<8);
|
||||
Fl::set_color(FL_SELECTION_COLOR,0,0,128);
|
||||
Root = new Fl_Root();
|
||||
#endif
|
||||
Fl_Root root;
|
||||
Root = &root;
|
||||
#if FL_MAJOR_VERSION>1
|
||||
// show() is not a virtual function in fltk2.0, this fools it:
|
||||
fltk::load_theme();
|
||||
root.show();
|
||||
#endif
|
||||
Root->show(argc,argv); // fools fltk into using -geometry to set the size
|
||||
XSetErrorHandler(xerror_handler);
|
||||
initialize();
|
||||
|
||||
Reference in New Issue
Block a user