Exemple #1
0
// create creates the window, initializes the keybind and mousebind packages
// and sets up the window to act like a real top-level client.
func (w *window) create() {
	keybind.Initialize(w.X)
	mousebind.Initialize(w.X)

	err := w.CreateChecked(w.X.RootWin(), 0, 0, flagWidth, flagHeight,
		xproto.CwBackPixel, 0xffffff)
	if err != nil {
		errLg.Fatalf("Could not create window: %s", err)
	}

	// Make the window close gracefully using the WM_DELETE_WINDOW protocol.
	w.WMGracefulClose(func(w *xwindow.Window) {
		xevent.Detach(w.X, w.Id)
		keybind.Detach(w.X, w.Id)
		mousebind.Detach(w.X, w.Id)
		w.Destroy()
		xevent.Quit(w.X)
	})

	// Set WM_STATE so it is interpreted as top-level and is mapped.
	err = icccm.WmStateSet(w.X, w.Id, &icccm.WmState{
		State: icccm.StateNormal,
	})
	if err != nil { // not a fatal error
		lg("Could not set WM_STATE: %s", err)
	}

	// _NET_WM_STATE = _NET_WM_STATE_NORMAL
	ewmh.WmStateSet(w.X, w.Id, []string{"_NET_WM_STATE_NORMAL"})

	// Set the name to something.
	w.nameSet("Decoding all images...")

	w.Map()
}
Exemple #2
0
func grabKeyboardAndMouse(m *Manager) {
	if m == nil {
		return
	}

	//go func() {
	X, err := xgbutil.NewConn()
	if err != nil {
		logger.Info("Get New Connection Failed:", err)
		return
	}
	keybind.Initialize(X)
	mousebind.Initialize(X)

	err = keybind.GrabKeyboard(X, X.RootWin())
	if err != nil {
		logger.Info("Grab Keyboard Failed:", err)
		return
	}

	grabAllMouseButton(X)

	xevent.ButtonPressFun(
		func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) {
			dbus.Emit(m, "KeyReleaseEvent", "")
			ungrabAllMouseButton(X)
			keybind.UngrabKeyboard(X)
			logger.Info("Button Press Event")
			xevent.Quit(X)
		}).Connect(X, X.RootWin())

	xevent.KeyPressFun(
		func(X *xgbutil.XUtil, e xevent.KeyPressEvent) {
			value := parseKeyEnvent(X, e.State, e.Detail)
			pressKeyStr = value
			dbus.Emit(m, "KeyPressEvent", value)
		}).Connect(X, X.RootWin())

	xevent.KeyReleaseFun(
		func(X *xgbutil.XUtil, e xevent.KeyReleaseEvent) {
			if strings.ToLower(pressKeyStr) == "super_l" ||
				strings.ToLower(pressKeyStr) == "super_r" {
				pressKeyStr = "Super"
			}

			dbus.Emit(m, "KeyReleaseEvent", pressKeyStr)
			pressKeyStr = ""
			ungrabAllMouseButton(X)
			keybind.UngrabKeyboard(X)
			logger.Infof("Key: %s\n", pressKeyStr)
			xevent.Quit(X)
		}).Connect(X, X.RootWin())

	xevent.Main(X)
	//}()
}
Exemple #3
0
func initialize() {
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	mousebind.Initialize(X)
	xWindow := newWindow(X, INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT)
	go xevent.Main(X)
	xorg.Initialize(
		egl.NativeWindowType(uintptr(xWindow.Id)),
		xorg.DefaultConfigAttributes,
		xorg.DefaultContextAttributes)
}
Exemple #4
0
func initEGL(controlCh *controlCh, width, height int) *platform.EGLState {
	X, err := xgbutil.NewConn()
	if err != nil {
		panic(err)
	}
	mousebind.Initialize(X)
	keybind.Initialize(X)
	xWindow := newWindow(controlCh, X, width, height)
	go xevent.Main(X)
	return xorg.Initialize(
		egl.NativeWindowType(uintptr(xWindow.Id)),
		xorg.DefaultConfigAttributes,
		xorg.DefaultContextAttributes,
	)
}
Exemple #5
0
func initialize() {
	var err error
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	mousebind.Initialize(X)
	newWindow(X)
	go xevent.Main(X)

	display = egl.GetDisplay(egl.DEFAULT_DISPLAY)
	if ok := egl.Initialize(display, nil, nil); !ok {
		egl.LogError(egl.GetError())
	}
	if ok := egl.ChooseConfig(display, attr, &config, 1, &numConfig); !ok {
		egl.LogError(egl.GetError())
	}
	if ok := egl.GetConfigAttrib(display, config, egl.NATIVE_VISUAL_ID, &vid); !ok {
		egl.LogError(egl.GetError())
	}
	egl.BindAPI(egl.OPENGL_ES_API)
	context = egl.CreateContext(display, config, egl.NO_CONTEXT, nil)
	surface = egl.CreateWindowSurface(display, config,
		egl.NativeWindowType(uintptr(X.RootWin())), nil)

	var val egl.Int
	if ok := egl.QuerySurface(display, &val, egl.WIDTH, surface); !ok {
		egl.LogError(egl.GetError())
	}

	if ok := egl.QuerySurface(display, &val, egl.HEIGHT, surface); !ok {
		egl.LogError(egl.GetError())
	}
	if ok := egl.GetConfigAttrib(display, config, egl.SURFACE_TYPE, &val); !ok {
		egl.LogError(egl.GetError())
	}
	gl.ClearColor(0.0, 0, 0, 1.0)

	p := Program(FragmentShader(fsh), VertexShader(vsh))
	gl.UseProgram(p)
	gl.BindAttribLocation(p, gl.Uint(attrPos), "pos")
	gl.BindAttribLocation(p, gl.Uint(attrColor), "color")
	uMatrix = gl.Int(gl.GetUniformLocation(p, "modelviewProjection"))

}
Exemple #6
0
func main() {
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Anytime the mousebind (keybind) package is used, mousebind.Initialize
	// *should* be called once. In the case of the mousebind package, this
	// isn't strictly necessary (currently!), but the 'Drag' features of
	// the mousebind package won't work without it.
	mousebind.Initialize(X)

	// Create two windows to prove we can close one while keeping the
	// other alive.
	newWindow(X)
	newWindow(X)

	xevent.Main(X)
}
Exemple #7
0
// newWindow creates the window, initializes the keybind and mousebind packages
// and sets up the window to act like a real top-level client.
func newWindow(X *xgbutil.XUtil) *Window {
	w, err := xwindow.Generate(X)
	if err != nil {
		errLg.Fatalf("Could not create window: %s", err)
	}

	keybind.Initialize(w.X)
	mousebind.Initialize(w.X)

	err = w.CreateChecked(w.X.RootWin(), 0, 0, 600, 600, xproto.CwBackPixel, 0xffffff)
	if err != nil {
		errLg.Fatalf("Could not create window: %s", err)
	}

	// Make the window close gracefully using the WM_DELETE_WINDOW protocol.
	w.WMGracefulClose(func(w *xwindow.Window) {
		xevent.Detach(w.X, w.Id)
		keybind.Detach(w.X, w.Id)
		mousebind.Detach(w.X, w.Id)
		w.Destroy()
		xevent.Quit(w.X)
	})

	// Set WM_STATE so it is interpreted as top-level and is mapped.
	err = icccm.WmStateSet(w.X, w.Id, &icccm.WmState{State: icccm.StateNormal})
	if err != nil {
		lg("Could not set WM_STATE: %s", err)
	}

	// _NET_WM_STATE = _NET_WM_STATE_NORMAL
	// not needed because we we set FS later anyway?
	//ewmh.WmStateSet(w.X, w.Id, []string{"_NET_WM_STATE_NORMAL"})

	w.Map()

	err = ewmh.WmStateReq(w.X, w.Id, ewmh.StateToggle, "_NET_WM_STATE_FULLSCREEN")
	if err != nil {
		lg("Failed to go FullScreen:", err)
	}
	return &Window{w}
}
Exemple #8
0
func main() {
	if flagWriteConfig {
		writeConfigFiles()
		os.Exit(0)
	}

	X, err := xgbutil.NewConn()
	if err != nil {
		logger.Error.Println(err)
		logger.Error.Fatalln("Error connecting to X, quitting...")
	}
	defer X.Conn().Close()

	// Do this first! Attempt to retrieve window manager ownership.
	// This includes waiting for any existing window manager to die.
	// 'own' also sets up handlers for quitting when a window manager tries
	// to replace *us*.
	if err := own(X, flagReplace); err != nil {
		logger.Error.Fatalf(
			"Could not establish window manager ownership: %s", err)
	}

	if len(flagConfigDir) > 0 {
		misc.ConfigPaths.Override = flagConfigDir
	}
	if len(flagDataDir) > 0 {
		misc.DataPaths.Override = flagDataDir
	}
	misc.ReadData()

	keybind.Initialize(X)
	mousebind.Initialize(X)
	focus.Initialize(X)
	stack.Initialize(X)
	cursors.Initialize(X)
	wm.Initialize(X, commands.Env, newHacks())
	hook.Initialize(commands.Env, misc.ConfigFile("hooks.wini"))

	// Listen to Root. It is all-important.
	err = xwindow.New(X, X.RootWin()).Listen(
		xproto.EventMaskPropertyChange |
			xproto.EventMaskFocusChange |
			xproto.EventMaskButtonPress |
			xproto.EventMaskButtonRelease |
			xproto.EventMaskStructureNotify |
			xproto.EventMaskSubstructureNotify |
			xproto.EventMaskSubstructureRedirect)
	if err != nil {
		logger.Error.Fatalf("Could not listen to Root window events: %s", err)
	}

	// Update state when the root window changes size
	wm.RootGeomChangeFun().Connect(X, wm.Root.Id)

	// Oblige map request events
	xevent.MapRequestFun(
		func(X *xgbutil.XUtil, ev xevent.MapRequestEvent) {
			xclient.New(ev.Window)
		}).Connect(X, wm.Root.Id)

	// Oblige configure requests from windows we don't manage.
	xevent.ConfigureRequestFun(
		func(X *xgbutil.XUtil, ev xevent.ConfigureRequestEvent) {
			// Make sure we aren't managing this client.
			if wm.FindManagedClient(ev.Window) != nil {
				return
			}

			xwindow.New(X, ev.Window).Configure(int(ev.ValueMask),
				int(ev.X), int(ev.Y), int(ev.Width), int(ev.Height),
				ev.Sibling, ev.StackMode)
		}).Connect(X, wm.Root.Id)

	xevent.FocusInFun(
		func(X *xgbutil.XUtil, ev xevent.FocusInEvent) {
			if ignoreRootFocus(ev.Mode, ev.Detail) {
				return
			}
			if len(wm.Workspace().Clients) == 0 {
				return
			}
			wm.FocusFallback()
		}).Connect(X, wm.Root.Id)

	// Listen to Root client message events. This is how we handle all
	// of the EWMH bullshit.
	xevent.ClientMessageFun(handleClientMessages).Connect(X, wm.Root.Id)

	// Tell everyone what we support.
	setSupported()

	// Start up the IPC command listener.
	go ipc()

	// Just before starting the main event loop, check to see if there are
	// any clients that already exist that we should manage.
	manageExistingClients()

	// Now make sure that clients are in the appropriate visible state.
	for _, wrk := range wm.Heads.Workspaces.Wrks {
		if wrk.IsVisible() {
			wrk.Show()
		} else {
			wrk.Hide()
		}
	}
	wm.Heads.ApplyStruts(wm.Clients)

	wm.FocusFallback()
	wm.Startup = false
	pingBefore, pingAfter, pingQuit := xevent.MainPing(X)

	if len(flagCpuProfile) > 0 {
		f, err := os.Create(flagCpuProfile)
		if err != nil {
			logger.Error.Fatalf("%s\n", err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if flagWingoRestarted {
		hook.Fire(hook.Restarted, hook.Args{})
	} else {
		hook.Fire(hook.Startup, hook.Args{})
	}

EVENTLOOP:
	for {
		select {
		case <-pingBefore:
			// Wait for the event to finish processing.
			<-pingAfter
		case f := <-commands.SafeExec:
			commands.SafeReturn <- f()
		case <-pingQuit:
			break EVENTLOOP
		}
	}
	if wm.Restart {
		// We need to tell the next invocation of Wingo that it is being
		// *restarted*. (So that we don't refire the startup hook.)
		// Thus, search os.Args for "--wingo-restarted". If it doesn't exist,
		// add it.
		found := false
		for _, arg := range os.Args {
			if strings.ToLower(strings.TrimSpace(arg)) == "--wingo-restarted" {
				found = true
			}
		}
		if !found {
			os.Args = append(os.Args, "--wingo-restarted")
		}
		logger.Message.Println("The user has told us to restart...\n\n\n")
		if err := syscall.Exec(os.Args[0], os.Args, os.Environ()); err != nil {
			logger.Error.Fatalf("Could not exec '%s': %s",
				strings.Join(os.Args, " "), err)
		}
	}
}
Exemple #9
0
func main() {
	if flagWriteConfig {
		writeConfigFiles()
		os.Exit(0)
	}

	X, err := xgbutil.NewConn()
	if err != nil {
		logger.Error.Println(err)
		logger.Error.Fatalln("Error connecting to X, quitting...")
	}
	defer X.Conn().Close()

	if flagShowSocket {
		showSocketPath(X)
		return
	}

	// Do this first! Attempt to retrieve window manager ownership.
	// This includes waiting for any existing window manager to die.
	// 'own' also sets up handlers for quitting when a window manager tries
	// to replace *us*.
	if err := own(X, flagReplace); err != nil {
		logger.Error.Fatalf(
			"Could not establish window manager ownership: %s", err)
	}

	if len(flagConfigDir) > 0 {
		misc.ConfigPaths.Override = flagConfigDir
	}
	if len(flagDataDir) > 0 {
		misc.DataPaths.Override = flagDataDir
	}
	misc.ReadData()

	keybind.Initialize(X)
	mousebind.Initialize(X)
	focus.Initialize(X)
	stack.Initialize(X)
	cursors.Initialize(X)
	wm.Initialize(X, commands.Env, newHacks())
	hook.Initialize(commands.Env, misc.ConfigFile("hooks.wini"))

	// Initialize event handlers on the root window.
	rootInit(X)

	// Tell everyone what we support.
	setSupported()

	// Start up the IPC command listener.
	go ipc(X)

	// And start up the IPC event notifier.
	go event.Notifier(X, socketFilePath(X))

	// Just before starting the main event loop, check to see if there are
	// any clients that already exist that we should manage.
	manageExistingClients()

	// Now make sure that clients are in the appropriate visible state.
	for _, wrk := range wm.Heads.Workspaces.Wrks {
		if wrk.IsVisible() {
			wrk.Show()
		} else {
			wrk.Hide()
		}
	}
	wm.Heads.ApplyStruts(wm.Clients)

	wm.FocusFallback()
	wm.Startup = false
	pingBefore, pingAfter, pingQuit := xevent.MainPing(X)

	if len(flagCpuProfile) > 0 {
		f, err := os.Create(flagCpuProfile)
		if err != nil {
			logger.Error.Fatalf("%s\n", err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if flagWingoRestarted {
		hook.Fire(hook.Restarted, hook.Args{})
	} else {
		hook.Fire(hook.Startup, hook.Args{})
	}

EVENTLOOP:
	for {
		select {
		case <-pingBefore:
			// Wait for the event to finish processing.
			<-pingAfter
		case f := <-commands.SafeExec:
			commands.SafeReturn <- f()
		case <-pingQuit:
			break EVENTLOOP
		}
	}
	if wm.Restart {
		event.Notify(event.Restarting{})
		for _, client := range wm.Clients {
			c := client.(*xclient.Client)

			if _, ok := c.Frame().(*frame.Full); ok {
				c.FrameNada()
			}
		}
		time.Sleep(1 * time.Second)

		// We need to tell the next invocation of Wingo that it is being
		// *restarted*. (So that we don't refire the startup hook.)
		// Thus, search os.Args for "--wingo-restarted". If it doesn't exist,
		// add it.
		found := false
		for _, arg := range os.Args {
			if strings.ToLower(strings.TrimSpace(arg)) == "--wingo-restarted" {
				found = true
			}
		}
		if !found {
			os.Args = append(os.Args, "--wingo-restarted")
		}
		logger.Message.Println("The user has told us to restart...\n\n\n")
		if err := syscall.Exec(os.Args[0], os.Args, os.Environ()); err != nil {
			logger.Error.Fatalf("Could not exec '%s': %s",
				strings.Join(os.Args, " "), err)
		}
	}
}
Exemple #10
0
func main() {
	X, err := xgbutil.NewConn()
	fatal(err)

	// Whenever the mousebind package is used, you must call Initialize.
	// Similarly for the keybind package.
	keybind.Initialize(X)
	mousebind.Initialize(X)

	// Easter egg! Use a right click to draw a gopher.
	gopherPng, _, err := image.Decode(bytes.NewBuffer(gopher.GopherPng()))
	fatal(err)

	// Now scale it to a reasonable size.
	gopher := xgraphics.Scale(gopherPng, gopherWidth, gopherHeight)

	// Create a new xgraphics.Image. It automatically creates an X pixmap for
	// you, and handles drawing to windows in the XDraw, XPaint and
	// XSurfaceSet functions.
	// N.B. An error is possible since X pixmap allocation can fail.
	canvas := xgraphics.New(X, image.Rect(0, 0, width, height))

	// Color in the background color.
	canvas.For(func(x, y int) xgraphics.BGRA {
		return bg
	})

	// Use the convenience function XShowExtra to create and map the
	// canvas window.
	// XShowExtra will also set the surface window of canvas for us.
	// We also use XShowExtra to set the name of the window and to quit the
	// main event loop when the window is closed.
	win := canvas.XShowExtra("Pointer painting", true)

	// Listen for pointer motion events and key press events.
	win.Listen(xproto.EventMaskButtonPress | xproto.EventMaskButtonRelease |
		xproto.EventMaskKeyPress)

	// The mousebind drag function runs three callbacks: one when the drag is
	// first started, another at each "step" in the drag, and a final one when
	// the drag is done.
	// The button sequence (in this case '1') is pressed, the first callback
	// is executed. If the first return value is true, the drag continues
	// and a pointer grab is initiated with the cursor id specified in the
	// second return value (use 0 to keep the cursor unchanged).
	// If it's false, the drag stops.
	// Note that Drag will automatically compress MotionNotify events.
	mousebind.Drag(X, win.Id, win.Id, "1", false,
		func(X *xgbutil.XUtil, rx, ry, ex, ey int) (bool, xproto.Cursor) {
			drawPencil(canvas, win, ex, ey)
			return true, 0
		},
		func(X *xgbutil.XUtil, rx, ry, ex, ey int) {
			drawPencil(canvas, win, ex, ey)
		},
		func(X *xgbutil.XUtil, rx, ry, ex, ey int) {})

	mousebind.Drag(X, win.Id, win.Id, "3", false,
		func(X *xgbutil.XUtil, rx, ry, ex, ey int) (bool, xproto.Cursor) {
			drawGopher(canvas, gopher, win, ex, ey)
			return true, 0
		},
		func(X *xgbutil.XUtil, rx, ry, ex, ey int) {
			drawGopher(canvas, gopher, win, ex, ey)
		},
		func(X *xgbutil.XUtil, rx, ry, ex, ey int) {})

	// Bind to the clear key specified, and just redraw the bg color.
	keybind.KeyPressFun(
		func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
			clearCanvas(canvas, win)
		}).Connect(X, win.Id, clearKey, false)

	// Bind a callback to each key specified in the 'pencils' color map.
	// The response is to simply switch the pencil color.
	for key, clr := range pencils {
		c := clr
		keybind.KeyPressFun(
			func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
				log.Printf("Changing pencil color to: %#v", c)
				pencil = c
			}).Connect(X, win.Id, key, false)
	}

	// Output some basic directions.
	fmt.Println("Use the left or right buttons on your mouse to paint " +
		"squares and gophers.")
	fmt.Println("Pressing numbers 1, 2, 3, 4, 5 or 6 will switch your pencil " +
		"color.")
	fmt.Println("Pressing 'c' will clear the canvas.")

	xevent.Main(X)
}
Exemple #11
0
func main() {
	var err error

	X, err = xgbutil.NewConn()
	if err != nil {
		logger.Error.Println(err)
		logger.Error.Println("Error connecting to X, quitting...")
		return
	}
	defer X.Conn().Close()

	keybind.Initialize(X)
	mousebind.Initialize(X)
	focus.Initialize(X)
	stack.Initialize(X)

	wingo = newWingoState()

	// Create a root window abstraction and load its geometry
	wingo.root = xwindow.New(X, X.RootWin())
	_, err = wingo.root.Geometry()
	if err != nil {
		logger.Error.Println("Could not get ROOT window geometry because: %v",
			err)
		logger.Error.Println("Cannot continue. Quitting...")
		return
	}

	// Load configuration
	wingo.conf, err = loadConfig()
	if err != nil {
		logger.Error.Println(err)
		logger.Error.Println("No configuration found. Quitting...")
		return
	}

	// Load theme
	wingo.theme, err = loadTheme(X)
	if err != nil {
		logger.Error.Println(err)
		logger.Error.Println("No theme configuration found. Quitting...")
		return
	}

	// Initialize prompts
	wingo.prompts = newPrompts()

	wingo.initializeHeads()

	// Attach all global key bindings
	attachAllKeys()

	// Attach all root mouse bindings
	rootMouseConfig()

	// Setup some cursors we use
	cursors.Setup(X)

	// Listen to Root. It is all-important.
	wingo.root.Listen(xproto.EventMaskPropertyChange |
		xproto.EventMaskStructureNotify |
		xproto.EventMaskSubstructureNotify |
		xproto.EventMaskSubstructureRedirect)

	// Update state when the root window changes size
	// xevent.ConfigureNotifyFun(rootGeometryChange).Connect(X, wingo.root.Id)

	// Oblige map request events
	xevent.MapRequestFun(
		func(X *xgbutil.XUtil, ev xevent.MapRequestEvent) {
			newClient(X, ev.Window)
		}).Connect(X, wingo.root.Id)

	// Oblige configure requests from windows we don't manage.
	xevent.ConfigureRequestFun(
		func(X *xgbutil.XUtil, ev xevent.ConfigureRequestEvent) {
			flags := int(ev.ValueMask) &
				^int(xproto.ConfigWindowSibling) &
				^int(xproto.ConfigWindowStackMode)
			xwindow.New(X, ev.Window).Configure(flags,
				int(ev.X), int(ev.Y), int(ev.Width), int(ev.Height),
				ev.Sibling, ev.StackMode)
		}).Connect(X, wingo.root.Id)

	// Listen to Root client message events.
	// We satisfy EWMH with these AND it also provides a mechanism
	// to issue commands using wingo-cmd.
	xevent.ClientMessageFun(commandHandler).Connect(X, wingo.root.Id)

	xevent.Main(X)
}
Exemple #12
0
func main() {
	// Connect to the X server using the DISPLAY environment variable.
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Anytime the mousebind (keybind) package is used, mousebind.Initialize
	// *should* be called once. In the case of the mousebind package, this
	// isn't strictly necessary, but the 'Drag' features of the mousebind
	// package won't work without it.
	mousebind.Initialize(X)

	// Before attaching callbacks, wrap them in a callback function type.
	// The mouse package exposes two such callback types:
	// mousebind.ButtonPressFun and mousebind.ButtonReleaseFun.
	cb1 := mousebind.ButtonPressFun(
		func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) {
			log.Println("Button press!")
		})

	// We can now attach the callback to a particular window and button
	// combination. This particular example grabs a button on the root window,
	// which makes it a global mouse binding.
	// Also, "Mod4-1" typically corresponds to pressing down the "Super" or
	// "Windows" key on your keyboard, and then pressing the left mouse button.
	// The last two parameters are whether to make a synchronous grab and
	// whether to actually issue a grab, respectively.
	// (The parameters used here are the common case.)
	// See the documentation for the Connect method for more details.
	err = cb1.Connect(X, X.RootWin(), "Mod4-1", false, true)

	// A mouse binding can fail if the mouse string could not be parsed, or if
	// you're trying to bind a button that has already been grabbed by another
	// client.
	if err != nil {
		log.Fatal(err)
	}

	// We can even attach multiple callbacks to the same button.
	err = mousebind.ButtonPressFun(
		func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) {
			log.Println("A second handler always happens after the first.")
		}).Connect(X, X.RootWin(), "Mod4-1", false, true)
	if err != nil {
		log.Fatal(err)
	}

	// Finally, if we want this client to stop responding to mouse events, we
	// can attach another handler that, when run, detaches all previous
	// handlers.
	// This time, we'll show an example of a ButtonRelease binding.
	err = mousebind.ButtonReleaseFun(
		func(X *xgbutil.XUtil, e xevent.ButtonReleaseEvent) {
			// Use mousebind.Detach to detach the root window
			// from all ButtonPress *and* ButtonRelease handlers.
			mousebind.Detach(X, X.RootWin())
			mousebind.Detach(X, X.RootWin())

			log.Printf("Detached all Button{Press,Release}Events from the "+
				"root window (%d).", X.RootWin())
		}).Connect(X, X.RootWin(), "Mod4-Shift-1", false, true)
	if err != nil {
		log.Fatal(err)
	}

	// Finally, start the main event loop. This will route any appropriate
	// ButtonPressEvents to your callback function.
	log.Println("Program initialized. Start pressing mouse buttons!")
	xevent.Main(X)
}
Exemple #13
0
func main() {

	// I don't want to retype all of these things
	// TODO: find/replace fatal with util.Fatal
	fatal := util.Fatal

	// establish X connection
	X, err := xgbutil.NewConn()
	fatal(err)

	// initiate extension tools
	shape.Init(X.Conn())
	mousebind.Initialize(X)

	// Detail our current window manager. Insures a minimum of EWMH compliance
	wm_name, err := ewmh.GetEwmhWM(X)
	fatal(err)
	log.Printf("Window manager: %s\n", wm_name)

	// create the cross UI
	cross_ui := makeCross(X)
	cross := cross_ui.Window

	// map the icons on the cross the the actions they should perform
	// when objects are dropped over them
	win_to_action := make(map[xproto.Window]wm.WindowInteraction)
	for name, icon := range cross_ui.Icons {
		if action, ok := wm.Actions[name]; ok {
			win_to_action[icon.Window.Id] = action
		} else {
			// otherwise,
			// shade the icon because it has no action attatched to it
			icon.SetState(ui.StateDisabled)
		}
	}

	// define handlers for the three parts of any drag-drop operation
	dm := util.DragManager{}
	handleDragStart := func(X *xgbutil.XUtil, rx, ry, ex, ey int) (cont bool, cursor xproto.Cursor) {
		// find the window we are trying to drag
		win, err := wm.FindManagedWindowUnderMouse(X)
		if err != nil {
			// don't continue the drag
			log.Printf("DragStart: could not get incoming window: %v\n", err)
			return false, 0
		}

		// cool awesome!
		dm.StartDrag(win)
		// continue the drag
		return true, 0
	}

	handleDragStep := func(X *xgbutil.XUtil, rx, ry, ex, ey int) {
		// see if we have a window that ISN'T the incoming window
		win, err := wm.FindManagedWindowUnderMouse(X)
		if err != nil {
			// whatever
			log.Printf("DragStep: no window found or something: %v\n", err)
			return
		}

		// oh we have a window? and it isn't the start window!? And not the current target!?
		if win != dm.Incoming && win != dm.Target {
			// reposition the cross over it
			// TODO: actually do this, center operates on rects, and all I have is this xproto.Window
			dm.SetTarget(win)

			// get the target width/height
			target_geom, err := xwindow.New(X, win).Geometry()
			if err != nil {
				log.Printf("DragStep: issues getting target geometry: %v\n", err)
				return
			}

			// set the target goemetry X, Y to the actual x, y relative to the root window
			tx, ty, err := wm.TranslateCoordinatesSync(X, win, X.RootWin(), 0, 0)
			if err != nil {
				log.Printf("DragStep: issue translating target coordinates to root coordinates: %v\n", err)
				return
			}
			target_geom.XSet(tx)
			target_geom.YSet(ty)
			x, y := util.CenterOver(cross.Geom, target_geom)
			cross.Move(x, y)
			cross.Map()
		}
	}

	handleDragEnd := func(X *xgbutil.XUtil, rx, ry, ex, ey int) {
		exit_early := false
		// get icon we are dropping over
		icon_win, _, err := wm.FindNextUnderMouse(X, cross.Id)
		if err != nil {
			log.Printf("DragEnd: icon not found: %v\n", err)
			exit_early = true
		}

		incoming, target, err := dm.EndDrag()
		// drag manager produces errors if we don't have both an Incoming and a Target yet
		if err != nil {
			log.Printf("DragEnd: drag manager state error: %v\n", err)
			exit_early = true
		}

		// we tried: hide UI
		cross.Unmap()

		// we had some sort of error, escape!
		if exit_early {
			return
		}

		// retrieve the action that this icon indicates
		if action, ok := win_to_action[icon_win]; ok {
			// create util-window objects from our window IDs
			if incoming_id, inc_ok := incoming.(xproto.Window); inc_ok {
				inc_win := xwindow.New(X, incoming_id)
				if target_id, t_ok := target.(xproto.Window); t_ok {
					t_win := xwindow.New(X, target_id)

					// perform the action!
					action(t_win, inc_win)

				} else {
					log.Println("DragEnd: target type error (was %v)\n", target)
				}
			} else {
				log.Println("DragEnd: incoming type error (was %v)\n", incoming)
			}
		} else {
			log.Printf("DragEnd: couldn't map window %v to an action", icon_win)
		}
	}

	mousebind.Drag(X, X.RootWin(), X.RootWin(), KeyComboMove, true,
		handleDragStart,
		handleDragStep,
		handleDragEnd)

	///////////////////////////////////////////////////////////////////////////
	// Window resizing behavior spike
	ManageResizingWindows(X)

	// start event loop, even though we have no events
	// to keep app from just closing
	xevent.Main(X)
}
Exemple #14
0
func openWin(X *xgbutil.XUtil) *xwindow.Window {
	mousebind.Initialize(X)
	win := newWindow(X, WINDOW_WIDTH, WINDOW_HEIGHT)
	go xevent.Main(X)
	return win
}