Skip to content
Browse files

Some chenages but segfault when focusing window

  • Loading branch information...
1 parent 2e3e5ae commit b65cf29266579159adbba3bacf35ca657edf12d5 @ziutek committed Dec 8, 2011
Showing with 139 additions and 78 deletions.
  1. +2 −0 Makefile
  2. +18 −11 box.go
  3. +1 −1 config.go
  4. +3 −2 event_handlers.go
  5. +15 −9 main.go
  6. +46 −38 manage.go
  7. +15 −0 utils.go
  8. +39 −17 window.go
View
2 Makefile
@@ -1,5 +1,7 @@
include $(GOROOT)/src/Make.inc
+GC = $Og -N
+
TARG=mdtwm
GOFILES=\
main.go\
View
29 box.go
@@ -5,15 +5,22 @@ import (
)
type Box struct {
- Frame Window // frame window of this box
- Window Window // window stored in this box
- Childs BoxList // child boxes contains childs of windows
+ Window Window // window stored in this box
+ Children BoxList // child boxes contains childs of windows
Float bool // floating box
}
func NewBox() *Box {
- return &Box{Childs: NewBoxList()}
+ return &Box{Children: NewBoxList()}
+}
+
+func (b *Box) Geometry() Geometry {
+ return b.Window.Geometry()
+}
+
+func (b *Box) SetGeometry(g Geometry) {
+ b.Window.SetGeometry(g)
}
type BoxList struct {
@@ -54,7 +61,7 @@ func (bl BoxList) BoxByWindow(w Window) *Box {
if b.Window == w {
return b
}
- b = b.Childs.BoxByWindow(w)
+ b = b.Children.BoxByWindow(w)
if b != nil {
return b
}
@@ -78,9 +85,9 @@ type BoxListIterator interface {
}
type boxListIterator struct {
- current *list.Element
+ current *list.Element
full_tree bool
- child BoxListIterator
+ child BoxListIterator
}
func (i *boxListIterator) Done() bool {
@@ -101,12 +108,12 @@ func (i *frontBoxListIterator) Next() (b *Box) {
i.child = nil // There is no more data in child iterator
}
if i.current == nil {
- return // There is no more data at all
+ return // There is no more data at all
}
b = i.current.Value.(*Box)
i.current = i.current.Next()
if i.full_tree {
- i.child = b.Childs.FrontIter(i.full_tree)
+ i.child = b.Children.FrontIter(i.full_tree)
}
return
}
@@ -125,12 +132,12 @@ func (i *backBoxListIterator) Next() (b *Box) {
i.child = nil // There is no more data in child iterator
}
if i.current == nil {
- return // There is no more data at all
+ return // There is no more data at all
}
b = i.current.Value.(*Box)
i.current = i.current.Prev()
if i.full_tree {
- i.child = b.Childs.BackIter(i.full_tree)
+ i.child = b.Children.BackIter(i.full_tree)
}
return
}
View
2 config.go
@@ -3,7 +3,7 @@ package main
func allocColor(r, g, b uint16) uint32 {
c, err := conn.AllocColor(screen.DefaultColormap, r, g, b)
if err != nil {
- l.Fatalf("Cannot allocate a color (%x,%x,%x): %v", r, g, b, err)
+ l.Fatalf("Cannot allocate a color (%x,%x,%x): %s", r, g, b, err)
}
return c.Pixel
}
View
5 event_handlers.go
@@ -9,18 +9,19 @@ func mapRequest(e xgb.MapRequestEvent) {
w := Window(e.Window)
if allDesks.BoxByWindow(w) == nil {
- winAdd(w)
+ winAdd(w, Window(e.Parent))
}
w.Map()
winFocus(w)
}
func enterNotify(e xgb.EnterNotifyEvent) {
+ l.Print("EnterNotifyEvent")
if e.Mode != xgb.NotifyModeNormal {
return
}
w := Window(e.Event)
- if currentDesk.Childs.BoxByWindow(w) != nil {
+ if currentDesk.Children.BoxByWindow(w) != nil {
winFocus(w)
}
}
View
24 main.go
@@ -9,11 +9,15 @@ import (
)
var (
- conn *xgb.Conn
- screen *xgb.ScreenInfo
- root Window
- currentDesk *Box // desk in mdtwm means workspace
- allDesks BoxList
+ conn *xgb.Conn
+ screen *xgb.ScreenInfo
+ root Window
+
+ // Desk in mdtwm means workspace. Desk contains panels. Panel contains
+ // windows. All they are described by Box structure.
+ allDesks BoxList
+ currentDesk *Box
+ currentPanel *Box
l = log.New(os.Stderr, "mdtwm: ", 0)
)
@@ -39,7 +43,7 @@ func signals() {
os.Exit(0)
}
}
- l.Printf("Signal %v received and ignored", sig)
+ l.Printf("Signal %s received and ignored", sig)
}
}()
}
@@ -53,15 +57,17 @@ func connect() {
var err error
conn, err = xgb.Dial(display)
if err != nil {
- l.Fatalf("Can't connect to %s display: %v", display, err)
+ l.Fatalf("Can't connect to %s display: %s", display, err)
}
screen = conn.DefaultScreen()
root = Window(screen.Root)
// Setup current desk (for now there is only one desk)
currentDesk = NewBox()
- currentDesk.Frame = root
currentDesk.Window = root
+ // For now there is only one panel in desk
+ currentPanel = newPanel(root.Geometry())
+ currentDesk.Children.PushFront(currentPanel)
allDesks = NewBoxList()
allDesks.PushFront(currentDesk)
@@ -85,7 +91,7 @@ func manageExistingWindows() {
}
for _, id := range tr.Children {
w := Window(id)
- winAdd(w)
+ winAdd(w, root)
w.Map()
}
}
View
84 manage.go
@@ -7,83 +7,91 @@ import (
const (
WindowEventMask = xgb.EventMaskPropertyChange |
- xgb.EventMaskStructureNotify |
- xgb.EventMaskFocusChange
-
- FrameEventMask = xgb.EventMaskButtonPress |
xgb.EventMaskButtonRelease |
//xgb.EventMaskPointerMotion |
xgb.EventMaskExposure | // window needs to be redrawn
- xgb.EventMaskStructureNotify | // frame gets destroyed
+ xgb.EventMaskStructureNotify | // window gets destroyed
xgb.EventMaskSubstructureRedirect | // app tries to resize itself
xgb.EventMaskSubstructureNotify | // subwindows get notifies
- xgb.EventMaskEnterWindow
+ xgb.EventMaskEnterWindow |
+ xgb.EventMaskFocusChange
)
var x int16
-func winAdd(w Window) {
+func winAdd(w, parent Window) {
l.Print("manageWindow: ", w)
if cfg.Ignore.Contains(w.Class()) {
return
}
+ b := NewBox()
+ b.Window = w
+
// Don't map if unvisible or has OverrideRedirect flag
attr := w.Attrs()
if attr.MapState != xgb.MapStateViewable || attr.OverrideRedirect {
return
}
- wm_type := propReplyAtoms(w.Prop(AtomNetWmWindowType, math.MaxUint32))
- if wm_type.Contains(AtomNetWmWindowTypeDock) {
- l.Printf("Window %v is of type dock")
+ // Check window type
+ p, err := w.Prop(AtomNetWmWindowType, math.MaxUint32)
+ if err != nil {
+ wm_type := propReplyAtoms(p)
+ if wm_type.Contains(AtomNetWmWindowTypeDock) {
+ l.Printf("Window %s is of type dock", w)
+ }
+ if cfg.Float.Contains(w.Class()) ||
+ wm_type.Contains(AtomNetWmWindowTypeDialog) ||
+ wm_type.Contains(AtomNetWmWindowTypeUtility) ||
+ wm_type.Contains(AtomNetWmWindowTypeToolbar) ||
+ wm_type.Contains(AtomNetWmWindowTypeSplash) {
+ b.Float = true
+ }
+ } else {
+ l.Printf("Can't get AtomNetWmWindowType from %s: %s", w, err)
}
// Grab left and right mouse buttons for click to focus/rasie
w.GrabButton(false, xgb.EventMaskButtonPress, xgb.GrabModeSync,
xgb.GrabModeAsync, root, xgb.CursorNone, 1, xgb.ButtonMaskAny)
w.GrabButton(false, xgb.EventMaskButtonPress, xgb.GrabModeSync,
xgb.GrabModeAsync, root, xgb.CursorNone, 3, xgb.ButtonMaskAny)
- b := NewBox()
- x, y, width, height := w.Geometry()
- b.Window = w
- b.Frame = CreateWindow(
- root, // TODO: Obtain parent box and set parent of frame from it
- x-int16(cfg.BorderWidth), y-int16(cfg.BorderWidth),
- width+cfg.BorderWidth*2, height+cfg.BorderWidth*2,
- xgb.WindowClassInputOutput,
- xgb.CWOverrideRedirect|xgb.CWEventMask,
- 1, FrameEventMask,
- )
- // Check it the window should be floating
- if cfg.Float.Contains(w.Class()) ||
- wm_type.Contains(AtomNetWmWindowTypeDialog) ||
- wm_type.Contains(AtomNetWmWindowTypeUtility) ||
- wm_type.Contains(AtomNetWmWindowTypeToolbar) ||
- wm_type.Contains(AtomNetWmWindowTypeSplash) {
- b.Float = true
- }
- // TODO: FrameMask for frame window not for child
w.SetEventMask(WindowEventMask)
-
// Nice bechavior if wm will be killed, exited, crashed
w.ChangeSaveSet(xgb.SetModeInsert)
-
w.SetBorderWidth(cfg.BorderWidth)
w.SetBorderColor(cfg.NormalBorderColor)
- w.SetGeometry(x, 0, 500, 700)
- x += 504
+ // Find box in which we have to put this window
+ pbox := currentPanel
+ if parent != root {
+ pbox = pbox.Children.BoxByWindow(parent)
+ }
+ tile(b, pbox)
+}
- currentDesk.Childs.PushFront(b)
+func tile(b, parent *Box) {
+ parent.Children.PushFront(b)
+ b.Window.Reparent(parent.Window, 100, 100)
+ //g := b.Geometry()
}
func winFocus(w Window) {
l.Print("Focusing window: ", w)
- for bi := currentDesk.Childs.FrontIter(true); !bi.Done(); {
+ for bi := currentDesk.Children.FrontIter(true); !bi.Done(); {
b := bi.Next()
if b.Window == w {
- b.Frame.SetBorderColor(cfg.FocusedBorderColor)
+ b.Window.SetBorderColor(cfg.FocusedBorderColor)
w.SetInputFocus()
} else {
- b.Frame.SetBorderColor(cfg.NormalBorderColor)
+ b.Window.SetBorderColor(cfg.NormalBorderColor)
}
}
}
+
+// Panel is a box with InputOnly (transparent) window in which a real windows
+// are placed. A desk is organized as collection of panels in some layout
+func newPanel(g Geometry) *Box {
+ p := NewBox()
+ p.Window = NewWindow(root, g, xgb.WindowClassInputOnly,
+ xgb.CWOverrideRedirect|xgb.CWEventMask, 1, WindowEventMask)
+ return p
+}
View
15 utils.go
@@ -3,6 +3,7 @@ package main
import (
"reflect"
"unsafe"
+ "math"
"x-go-binding.googlecode.com/hg/xgb"
)
@@ -28,3 +29,17 @@ func propReplyAtoms(prop *xgb.GetPropertyReply) IdList {
num_atoms := prop.ValueLen / uint32(atom_size)
return (*[1<<24]xgb.Id)(unsafe.Pointer(&prop.Value[0]))[:num_atoms]
}
+
+func Int16(x int) int16 {
+ if x > math.MaxInt16 || x < math.MinInt16 {
+ panic("Can't convert int to int16")
+ }
+ return int16(x)
+}
+
+func Uint16(x int) uint16 {
+ if x > math.MaxUint16 || x < 0 {
+ panic("Can't convert int to uint16")
+ }
+ return uint16(x)
+}
View
56 window.go
@@ -6,16 +6,37 @@ import (
"x-go-binding.googlecode.com/hg/xgb"
)
+type Geometry struct {
+ X, Y int16
+ W, H uint16
+}
+
+func (g Geometry) Enlarge(i int) Geometry {
+ d := i + i
+ return Geometry{
+ Int16(int(g.X) - i), Int16(int(g.Y) - i),
+ Uint16(int(g.W) + d), Uint16(int(g.H) + d),
+ }
+}
+
+func (g Geometry) EnlargeH(i int) Geometry {
+ return Geometry{Int16(int(g.X) - i), g.Y, Uint16(int(g.W) + i + i), g.H}
+}
+
+func (g Geometry) EnlargeV(i int) Geometry {
+ return Geometry{g.X, Int16(int(g.Y) - i), g.W, Uint16(int(g.H) + i + i)}
+}
+
type Window xgb.Id
// Creates unmaped window with border == 0
-func CreateWindow(parent Window, x, y int16, width, height, class uint16,
+func NewWindow(parent Window, g Geometry, class uint16,
mask uint32, vals ...uint32) Window {
id := conn.NewId()
conn.CreateWindow(
xgb.WindowClassCopyFromParent,
id,parent.Id(),
- x, y, width, height, 0,
+ g.X, g.Y, g.W, g.H, 0,
class, xgb.WindowClassCopyFromParent,
mask, vals,
)
@@ -50,37 +71,32 @@ func (w Window) SetInputFocus() {
conn.SetInputFocus(xgb.InputFocusPointerRoot, w.Id(), xgb.TimeCurrentTime)
}
-func (w Window) Geometry() (x, y int16, width, height uint16) {
+func (w Window) Geometry() Geometry {
g, err := conn.GetGeometry(w.Id())
if err != nil {
- l.Fatal("Can't get geometry of window %v: %v", w, err)
+ l.Fatal("Can't get geometry of window %s: %s", w, err)
}
- return g.X, g.Y, g.Width, g.Height
+ return Geometry{g.X, g.Y, g.Width, g.Height}
}
-func (w Window) SetGeometry(x, y int16, width, height uint16) {
+func (w Window) SetGeometry(g Geometry) {
w.Configure(
xgb.ConfigWindowX|xgb.ConfigWindowY|
xgb.ConfigWindowWidth|xgb.ConfigWindowHeight,
- uint32(x), uint32(y), uint32(width), uint32(height),
+ uint32(g.X), uint32(g.Y), uint32(g.W), uint32(g.H),
)
}
func (w Window) Attrs() *xgb.GetWindowAttributesReply {
a, err := conn.GetWindowAttributes(w.Id())
if err != nil {
- l.Fatalf("Can't get attributes of window %v: %v", w, err)
+ l.Fatalf("Can't get attributes of window %s: %s", w, err)
}
return a
}
-func (w Window) Prop(prop xgb.Id, max uint32) *xgb.GetPropertyReply {
- p, err := conn.GetProperty(false, w.Id(), prop, xgb.GetPropertyTypeAny, 0,
- max)
- if err != nil {
- l.Fatalf("Can't get property of window %v: %v", w, err)
- }
- return p
+func (w Window) Prop(prop xgb.Id, max uint32) (*xgb.GetPropertyReply, error) {
+ return conn.GetProperty(false, w.Id(), prop, xgb.GetPropertyTypeAny, 0, max)
}
func (w Window) ChangeProp(mode byte, prop, typ xgb.Id, data interface{}) {
@@ -116,12 +132,18 @@ func (w Window) ChangeProp(mode byte, prop, typ xgb.Id, data interface{}) {
}
func (w Window) Name() string {
- p := w.Prop(xgb.AtomWmName, 128)
+ p, err := w.Prop(xgb.AtomWmName, 128)
+ if err != nil {
+ return ""
+ }
return string(p.Value)
}
func (w Window) Class() string {
- p := w.Prop(xgb.AtomWmClass, 128)
+ p, err := w.Prop(xgb.AtomWmClass, 128)
+ if err != nil {
+ return ""
+ }
return string(p.Value)
}

0 comments on commit b65cf29

Please sign in to comment.
Something went wrong with that request. Please try again.