func (app *RuntimeApp) Activate(x, y int32) error { //TODO: handle multiple xids switch { case !contains(app.state, "_NET_WM_STATE_FOCUSED"): activateWindow(app.CurrentInfo.Xid) case contains(app.state, "_NET_WM_STATE_FOCUSED"): s, err := icccm.WmStateGet(XU, app.CurrentInfo.Xid) if err != nil { logger.Info("WmStateGetError:", s, err) return err } switch s.State { case icccm.StateIconic: s.State = icccm.StateNormal icccm.WmStateSet(XU, app.CurrentInfo.Xid, s) case icccm.StateNormal: activeXid, _ := ewmh.ActiveWindowGet(XU) logger.Debugf("%s, 0x%x(c), 0x%x(a), %v", app.Id, app.CurrentInfo.Xid, activeXid, app.state) if len(app.xids) == 1 { s.State = icccm.StateIconic iconifyWindow(app.CurrentInfo.Xid) } else { logger.Warningf("activeXid is 0x%x, current is 0x%x", activeXid, app.CurrentInfo.Xid) if activeXid == app.CurrentInfo.Xid { x := app.findNextLeader() ewmh.ActiveWindowReq(XU, x) } } } } return nil }
func main() { X, _ := xgbutil.Dial("") active, _ := ewmh.ActiveWindowGet(X) geom, err := xwindow.GetGeometry(X, active) if err != nil { fmt.Println(err) } else { fmt.Println(geom) } // ewmh.WmStateReqExtra(X, active, ewmh.StateToggle, // "_NET_WM_STATE_MAXIMIZED_VERT", // "_NET_WM_STATE_MAXIMIZED_HORZ", 2) time.Sleep(time.Millisecond) // err = xwindow.MoveResize(X, active, geom.X, geom.Y, // geom.Width - 100, geom.Height) fmt.Println(err) fmt.Printf("\n") rgeom, err := xwindow.RawGeometry(X, X.RootWin()) if err != nil { fmt.Println(err) } else { fmt.Println(rgeom) } X.Conn().Close() }
//GetClients get windows list func GetClients() []Client { clients := []Client{} var err error X, err = xgbutil.NewConn() if err != nil { log.Fatal(err) } wids, err := ewmh.ClientListGet(X) if err != nil { log.Fatal(err) } a, _ := ewmh.ActiveWindowGet(X) for _, wid := range wids { name, err := ewmh.WmNameGet(X, wid) if name == "Shadow" { SHADOW = wid continue } if err != nil { // not a fatal error log.Println(err) name = "" } desk, _ := ewmh.WmDesktopGet(X, wid) class, _ := icccm.WmClassGet(X, wid) clients = append(clients, Client{ wid, name, desk, wid == a, class.Class, }) } return clients }
func getActiveWindow(X *xgbutil.XUtil) (uint32, error) { xid, err := ewmh.ActiveWindowGet(X) if err != nil { logger.Warning("Get active window failed:", err) return 0, err } return uint32(xid), nil }
func (wa *fullScreenWorkaround) start() { var runner func() runner = func() { w, _ := ewmh.ActiveWindowGet(wa.xu) wa.detectTarget(w) time.AfterFunc(time.Second*5, runner) } runner() root := xwindow.New(wa.xu, wa.xu.RootWin()) root.Listen(xproto.EventMaskPropertyChange) xevent.PropertyNotifyFun(func(XU *xgbutil.XUtil, ev xevent.PropertyNotifyEvent) { if wa.activeWindowAtom == ev.Atom { w, _ := ewmh.ActiveWindowGet(XU) wa.detectTarget(w) } }).Connect(wa.xu, root.Id) xevent.Main(wa.xu) }
func main() { X, _ := xgbutil.NewConn() active, err := ewmh.ActiveWindowGet(X) wmName, err := icccm.WmNameGet(X, active) showTest("WM_NAME get", wmName, err) err = icccm.WmNameSet(X, active, "hooblah") wmName, _ = icccm.WmNameGet(X, active) showTest("WM_NAME set", wmName, err) wmNormHints, err := icccm.WmNormalHintsGet(X, active) showTest("WM_NORMAL_HINTS get", wmNormHints, err) wmNormHints.Width += 5 err = icccm.WmNormalHintsSet(X, active, wmNormHints) showTest("WM_NORMAL_HINTS set", wmNormHints, err) wmHints, err := icccm.WmHintsGet(X, active) showTest("WM_HINTS get", wmHints, err) wmHints.InitialState = icccm.StateNormal err = icccm.WmHintsSet(X, active, wmHints) showTest("WM_NORMAL_HINTS set", wmHints, err) wmClass, err := icccm.WmClassGet(X, active) showTest("WM_CLASS get", wmClass, err) wmClass.Instance = "hoopdy hoop" err = icccm.WmClassSet(X, active, wmClass) showTest("WM_CLASS set", wmClass, err) wmTrans, err := icccm.WmTransientForGet(X, active) showTest("WM_TRANSIENT_FOR get", wmTrans, err) wmProts, err := icccm.WmProtocolsGet(X, active) showTest("WM_PROTOCOLS get", wmProts, err) wmClient, err := icccm.WmClientMachineGet(X, active) showTest("WM_CLIENT_MACHINE get", wmClient, err) err = icccm.WmClientMachineSet(X, active, "Leopard") wmClient, _ = icccm.WmClientMachineGet(X, active) showTest("WM_CLIENT_MACHINE set", wmClient, err) wmState, err := icccm.WmStateGet(X, active) showTest("WM_STATE get", wmState, err) wmState.Icon = xproto.Window(8365538) wmState.State = icccm.StateNormal err = icccm.WmStateSet(X, active, wmState) wmState, _ = icccm.WmStateGet(X, active) showTest("WM_STATE set", wmState, err) }
func main() { X, _ := xgbutil.NewConn() active, _ := ewmh.ActiveWindowGet(X) mh, err := motif.WmHintsGet(X, active) if err != nil { fmt.Println(err) } else { fmt.Println(mh) fmt.Println("Does Chrome want decorations?", motif.Decor(X, active, mh)) } }
func main() { defer Recovery() X, Xerr = xgbutil.Dial("") if Xerr != nil { panic(Xerr) } active, _ := ewmh.ActiveWindowGet(X) icons, _ := ewmh.WmIconGet(X, active) var width, height int = 300, 300 work := xgraphics.FindBestIcon(width, height, icons) if work != nil { fmt.Printf("Working with icon (%d, %d)\n", work.Width, work.Height) } else { fmt.Println("No good icon... :-(") return } eimg, emask := xgraphics.EwmhIconToImage(work) img := xgraphics.Scale(eimg, int(width), int(height)) mask := xgraphics.Scale(emask, int(width), int(height)) dest := xgraphics.BlendBg(img, mask, 100, color.RGBA{0, 0, 255, 255}) // Let's try to write some text... // xgraphics.DrawText(dest, 50, 50, color.RGBA{255, 255, 255, 255}, 20, // fontFile, "Hello, world!") // tw, th, err := xgraphics.TextExtents(fontFile, 11, "Hiya") // fmt.Println(tw, th, err) win := xgraphics.CreateImageWindow(X, dest, 3940, 0) X.Conn().MapWindow(win) // time.Sleep(20 * time.Second) select {} }
func getActiveApp(X *xgbutil.XUtil) (app App) { active, err := ewmh.ActiveWindowGet(X) if err != nil { log.Fatal(err) } app.PID, err = ewmh.WmPidGet(X, active) if err != nil { log.Println("Couldn't get PID of window (0x%x)", active) } app.Name, err = ewmh.WmNameGet(X, active) if err != nil || len(app.Name) == 0 { app.Name, err = icccm.WmNameGet(X, active) // If we still can't find anything, give up. if err != nil || len(app.Name) == 0 { app.Name = "N/A" } } return }
func (ams *AppMenuSource) Open(ct *CommandTray) bool { ams.app = nil ams.menu = nil active, err := ewmh.ActiveWindowGet(ct.X) if err != nil { return false } uniqName, err := xprop.PropValStr(xprop.GetProperty(ct.X, active, "_GTK_UNIQUE_BUS_NAME")) if err != nil { return false } pathMenu, err := xprop.PropValStr(xprop.GetProperty(ct.X, active, "_GTK_APP_MENU_OBJECT_PATH")) if err != nil { return false } pathApp, err := xprop.PropValStr(xprop.GetProperty(ct.X, active, "_GTK_APPLICATION_OBJECT_PATH")) if err != nil { return false } // Done parsing props! Yay! ams.app = &utils.GtkActions{ ams.Conn.Object(uniqName, dbus.ObjectPath(pathApp)), } ams.menu = &utils.GtkMenu{ ams.Conn.Object(uniqName, dbus.ObjectPath(pathMenu)), } return true }
func (s *Setting) init() bool { s.core = gio.NewSettings(SchemaId) if s.core == nil { return false } s.listenSettingChange(HideModeKey, func(g *gio.Settings, key string) { s.hideModeLock.Lock() defer s.hideModeLock.Unlock() value := HideModeType(g.GetEnum(key)) s.hideMode = value logger.Debug(key, "changed to", key) dbus.Emit(s, "HideModeChanged", int32(value)) }) s.listenSettingChange(DisplayModeKey, func(g *gio.Settings, key string) { s.displayModeLock.Lock() defer s.displayModeLock.Unlock() value := DisplayModeType(g.GetEnum(key)) logger.Debug(key, "changed to", value) s.displayMode = value for _, rApp := range ENTRY_MANAGER.runtimeApps { rebuildXids := []xproto.Window{} for xid, _ := range rApp.xids { if _, err := xprop.PropValStr( xprop.GetProperty( XU, xid, "_DDE_DOCK_APP_ID", ), ); err != nil { continue } rebuildXids = append(rebuildXids, xid) rApp.detachXid(xid) } l := len(rebuildXids) if l == 0 { continue } if len(rApp.xids) == 0 { ENTRY_MANAGER.destroyRuntimeApp(rApp) } newApp := ENTRY_MANAGER.createRuntimeApp(rebuildXids[0]) for i := 0; i < l; i++ { newApp.attachXid(rebuildXids[i]) } activeXid, err := ewmh.ActiveWindowGet(XU) if err != nil { continue } for xid, _ := range newApp.xids { logger.Debugf("through new app xids") if activeXid == xid { logger.Debugf("0x%x(a), 0x%x(x)", activeXid, xid) newApp.setLeader(xid) newApp.updateState(xid) ewmh.ActiveWindowSet(XU, xid) break } } } dockProperty.updateDockHeight(value) dbus.Emit(s, "DisplayModeChanged", int32(value)) }) s.listenSettingChange(ClockTypeKey, func(*gio.Settings, string) { s.clockTypeLock.Lock() defer s.clockTypeLock.Unlock() s.clockType = ClockType(s.core.GetEnum(ClockTypeKey)) dbus.Emit(s, "ClockTypeChanged", int32(s.clockType)) }) s.listenSettingChange(DisplayDateKey, func(*gio.Settings, string) { s.displayDateLock.Lock() defer s.displayDateLock.Unlock() s.displayDate = s.core.GetBoolean(DisplayDateKey) dbus.Emit(s, "DisplayDateChanged", s.displayDate) }) s.listenSettingChange(DisplayWeekKey, func(*gio.Settings, string) { s.displayWeekLock.Lock() defer s.displayWeekLock.Unlock() s.displayWeek = s.core.GetBoolean(DisplayWeekKey) dbus.Emit(s, "DisplayWeekChanged", s.displayWeek) }) // at least one read operation must be called after signal connected, otherwise, // the signal connection won't work from glib 2.43. // NB: https://github.com/GNOME/glib/commit/8ff5668a458344da22d30491e3ce726d861b3619 s.displayMode = DisplayModeType(s.core.GetEnum(DisplayModeKey)) s.hideMode = HideModeType(s.core.GetEnum(HideModeKey)) if s.hideMode == HideModeAutoHide { s.hideMode = HideModeSmartHide s.core.SetEnum(HideModeKey, int32(HideModeSmartHide)) } s.clockType = ClockType(s.core.GetEnum(ClockTypeKey)) s.displayDate = s.core.GetBoolean(DisplayDateKey) s.displayWeek = s.core.GetBoolean(DisplayWeekKey) return true }
func (m *ClientManager) listenRootWindow() { var update = func() { list, err := ewmh.ClientListGet(XU) if err != nil { logger.Warning("Can't Get _NET_CLIENT_LIST", err) } isLauncherShown = false for _, xid := range list { if !isDeepinLauncher(xid) { continue } winProps, err := xproto.GetWindowAttributes(XU.Conn(), xid).Reply() if err != nil { break } if winProps.MapState == xproto.MapStateViewable { isLauncherShown = true } break } ENTRY_MANAGER.runtimeAppChanged(list) } xwindow.New(XU, XU.RootWin()).Listen(xproto.EventMaskPropertyChange) xevent.PropertyNotifyFun(func(XU *xgbutil.XUtil, ev xevent.PropertyNotifyEvent) { switch ev.Atom { case _NET_CLIENT_LIST: update() case _NET_ACTIVE_WINDOW: var err error isLauncherShown = false if activeWindow, err = ewmh.ActiveWindowGet(XU); err == nil { appId := find_app_id_by_xid(activeWindow, DisplayModeType(setting.GetDisplayMode())) logger.Debug("current active window:", appId) if rApp, ok := ENTRY_MANAGER.runtimeApps[appId]; ok { logger.Debug("find runtime app") rApp.setLeader(activeWindow) rApp.updateState(activeWindow) } logger.Debug("active window is", appId) if appId != DDELauncher { LAUNCHER, err := launcher.NewLauncher( "com.deepin.dde.launcher", "/com/deepin/dde/launcher", ) if err != nil { logger.Debug(err) } else { LAUNCHER.Hide() launcher.DestroyLauncher(LAUNCHER) } } else { isLauncherShown = true } lastActive = appId dbus.Emit(m, "ActiveWindowChanged", uint32(activeWindow)) } hideMode := HideModeType(setting.GetHideMode()) if hideMode == HideModeSmartHide || hideMode == HideModeKeepHidden { hideModemanager.UpdateState() } case _NET_SHOWING_DESKTOP: dbus.Emit(m, "ShowingDesktopChanged") case DEEPIN_SCREEN_VIEWPORT: updateCurrentViewport() } }).Connect(XU, XU.RootWin()) update() xevent.Main(XU) }
func (self *SessionModule) GetWindow(window_id string) (SessionWindow, error) { window := SessionWindow{} if id, err := self.toX11WindowId(window_id); err == nil { xgbWindow := xwindow.New(self.X, id) geom, _ := xgbWindow.DecorGeometry() process := SessionProcess{} window.ID = uint32(id) window.Title, _ = ewmh.WmNameGet(self.X, id) //window.IconUri = r.Path() + "/" + id windowWorkspace, _ := ewmh.WmDesktopGet(self.X, id) activeWinId, _ := ewmh.ActiveWindowGet(self.X) if windowWorkspace == 0xFFFFFFFF { window.AllWorkspaces = true } else { window.Workspace = windowWorkspace } if id == activeWinId { window.Active = true } // calculate window dimensions from desktop and window frame boundaries window.Dimensions.Width = uint(geom.Width()) window.Dimensions.Height = uint(geom.Height()) window.Dimensions.X = geom.X() window.Dimensions.Y = geom.Y() // fill in process details process.PID, _ = ewmh.WmPidGet(self.X, id) window.Process = process // get window state flags window.Flags = make(map[string]bool) // minimized if self.x11HasWmState(id, `_NET_WM_STATE_HIDDEN`) { window.Flags["minimized"] = true } // shaded if self.x11HasWmState(id, `_NET_WM_STATE_SHADED`) { window.Flags[`shaded`] = true } // maximized if self.x11HasWmState(id, `_NET_WM_STATE_MAXIMIZED_VERT`) && self.x11HasWmState(id, `_NET_WM_STATE_MAXIMIZED_HORZ`) { window.Flags[`maximized`] = true } // above if self.x11HasWmState(id, `_NET_WM_STATE_ABOVE`) { window.Flags[`above`] = true } // below if self.x11HasWmState(id, `_NET_WM_STATE_BELOW`) { window.Flags[`below`] = true } // urgent if self.x11HasWmState(id, `_NET_WM_STATE_DEMANDS_ATTENTION`) { window.Flags[`urgent`] = true } // skip_taskbar if self.x11HasWmState(id, `_NET_WM_STATE_SKIP_TASKBAR`) { window.Flags[`skip_taskbar`] = true } // skip_pager if self.x11HasWmState(id, `_NET_WM_STATE_SKIP_PAGER`) { window.Flags[`skip_pager`] = true } // sticky if self.x11HasWmState(id, `_NET_WM_STATE_STICKY`) { window.Flags[`sticky`] = true } // fullscreen if self.x11HasWmState(id, `_NET_WM_STATE_FULLSCREEN`) { window.Flags[`fullscreen`] = true } // modal if self.x11HasWmState(id, `_NET_WM_STATE_MODAL`) { window.Flags[`modal`] = true } // ICCCM WM_CLASS instance if wmClass, err := icccm.WmClassGet(self.X, id); err == nil { window.ClassInstance = wmClass.Instance window.ClassName = wmClass.Class if entry, ok := self.Applications.Entries[window.ClassInstance]; ok { window.EntryName = entry.Key } } return window, nil } else { return window, err } }
func main() { X, Xerr = xgbutil.NewConn() if Xerr != nil { panic(Xerr) } active, _ := ewmh.ActiveWindowGet(X) parent, _ := xwindow.ParentWindow(X, active) actOpacity, _ := ewmh.WmWindowOpacityGet(X, parent) fmt.Printf("Opacity for active window: %f\n", actOpacity) showDesk, _ := ewmh.ShowingDesktopGet(X) fmt.Printf("Showing desktop? %v\n", showDesk) wmName, err := ewmh.GetEwmhWM(X) if err != nil { fmt.Printf("No conforming window manager found... :-(\n") fmt.Println(err) } else { fmt.Printf("Window manager: %s\n", wmName) } pager := xproto.Window(0x160001e) middle := xproto.Window(0x3200016) geom, _ := ewmh.DesktopGeometryGet(X) desktops, _ := ewmh.DesktopNamesGet(X) curdesk, _ := ewmh.CurrentDesktopGet(X) clients, _ := ewmh.ClientListGet(X) activeName, _ := ewmh.WmNameGet(X, active) fmt.Printf("Active window: %x\n", active) fmt.Printf("Current desktop: %d\n", curdesk) fmt.Printf("Client list: %v\n", clients) fmt.Printf("Desktop geometry: (width: %d, height: %d)\n", geom.Width, geom.Height) fmt.Printf("Active window name: %s\n", activeName) fmt.Printf("Desktop names: %s\n", desktops) var desk string if curdesk < len(desktops) { desk = desktops[curdesk] } else { desk = string(curdesk) } fmt.Printf("Current desktop: %s\n", desk) // fmt.Printf("\nChanging current desktop to 25 from %d\n", curdesk) ewmh.CurrentDesktopSet(X, curdesk) // fmt.Printf("Current desktop is now: %d\n", ewmh.CurrentDesktop(X)) fmt.Printf("Setting active win to %x\n", middle) // ewmh.ActiveWindowReq(X, middle) rand.Seed(int64(time.Now().Nanosecond())) randStr := make([]byte, 20) for i, _ := range randStr { if rf := rand.Float32(); rf < 0.40 { randStr[i] = byte('a' + rand.Intn('z'-'a')) } else if rf < 0.80 { randStr[i] = byte('A' + rand.Intn('Z'-'A')) } else { randStr[i] = ' ' } } ewmh.WmNameSet(X, active, string(randStr)) newName, _ := ewmh.WmNameGet(X, active) fmt.Printf("New name: %s\n", newName) // deskNames := ewmh.DesktopNamesGet(X) // fmt.Printf("Desktop names: %s\n", deskNames) // deskNames[len(deskNames) - 1] = "xgbutil" // ewmh.DesktopNamesSet(X, deskNames) // fmt.Printf("Desktop names: %s\n", ewmh.DesktopNamesGet(X)) supported, _ := ewmh.SupportedGet(X) fmt.Printf("Supported hints: %v\n", supported) fmt.Printf("Setting supported hints...\n") ewmh.SupportedSet(X, []string{"_NET_CLIENT_LIST", "_NET_WM_NAME", "_NET_WM_DESKTOP"}) numDesks, _ := ewmh.NumberOfDesktopsGet(X) fmt.Printf("Number of desktops: %d\n", numDesks) // ewmh.NumberOfDesktopsReq(X.EwmhNumberOfDesktops(X) + 1) // time.Sleep(time.Second) // fmt.Printf("Number of desktops: %d\n", ewmh.NumberOfDesktops(X)) viewports, _ := ewmh.DesktopViewportGet(X) fmt.Printf("Viewports (%d): %v\n", len(viewports), viewports) // viewports[2].X = 50 // viewports[2].Y = 293 // ewmh.DesktopViewportSet(X, viewports) // time.Sleep(time.Second) // // viewports = ewmh.DesktopViewport(X) // fmt.Printf("Viewports (%d): %v\n", len(viewports), viewports) // ewmh.CurrentDesktopReq(X, 3) visDesks, _ := ewmh.VisibleDesktopsGet(X) workarea, _ := ewmh.WorkareaGet(X) fmt.Printf("Visible desktops: %v\n", visDesks) fmt.Printf("Workareas: %v\n", workarea) // fmt.Printf("Virtual roots: %v\n", ewmh.VirtualRoots(X)) // fmt.Printf("Desktop layout: %v\n", ewmh.DesktopLayout(X)) fmt.Printf("Closing window %x\n", 0x2e004c5) ewmh.CloseWindow(X, 0x1e00cdf) fmt.Printf("Moving/resizing window: %x\n", 0x2e004d0) ewmh.MoveresizeWindow(X, 0x2e004d0, 1920, 30, 500, 500) // fmt.Printf("Trying to initiate a moveresize...\n") // ewmh.WmMoveresize(X, 0x2e004db, xgbutil.EwmhMove) // time.Sleep(5 * time.Second) // ewmh.WmMoveresize(X, 0x2e004db, xgbutil.EwmhCancel) // fmt.Printf("Stacking window %x...\n", 0x2e00509) // ewmh.RestackWindow(X, 0x2e00509) fmt.Printf("Requesting frame extents for active window...\n") ewmh.RequestFrameExtents(X, active) activeDesk, _ := ewmh.WmDesktopGet(X, active) activeType, _ := ewmh.WmWindowTypeGet(X, active) fmt.Printf("Active window's desktop: %d\n", activeDesk) fmt.Printf("Active's types: %v\n", activeType) // fmt.Printf("Pager's types: %v\n", ewmh.WmWindowType(X, 0x180001e)) // fmt.Printf("Pager's state: %v\n", ewmh.WmState(X, 0x180001e)) // ewmh.WmStateReq(X, active, xgbutil.EwmhStateToggle, // "_NET_WM_STATE_HIDDEN") // ewmh.WmStateReqExtra(X, active, xgbutil.EwmhStateToggle, // "_NET_WM_STATE_MAXIMIZED_VERT", // "_NET_WM_STATE_MAXIMIZED_HORZ", 2) activeAllowed, _ := ewmh.WmAllowedActionsGet(X, active) fmt.Printf("Allowed actions on active: %v\n", activeAllowed) struts, err := ewmh.WmStrutGet(X, pager) if err != nil { fmt.Printf("Pager struts: %v\n", err) } else { fmt.Printf("Pager struts: %v\n", struts) } pstruts, err := ewmh.WmStrutPartialGet(X, pager) if err != nil { fmt.Printf("Pager struts partial: %v - %v\n", pstruts, err) } else { fmt.Printf("Pager struts partial: %v\n", pstruts.BottomStartX) } // fmt.Printf("Icon geometry for active: %v\n", // ewmh.WmIconGeometry(X, active)) icons, _ := ewmh.WmIconGet(X, active) fmt.Printf("Active window's (%x) icon data: (length: %v)\n", active, len(icons)) for _, icon := range icons { fmt.Printf("\t(%d, %d)", icon.Width, icon.Height) fmt.Printf(" :: %d == %d\n", icon.Width*icon.Height, len(icon.Data)) } // fmt.Printf("Now set them again...\n") // ewmh.WmIconSet(X, active, icons[:len(icons) - 1]) }
func main() { defer Recovery() X, Xerr = xgbutil.Dial("") if Xerr != nil { panic(Xerr) } active, _ := ewmh.ActiveWindowGet(X) icons, _ := ewmh.WmIconGet(X, active) fmt.Printf("Active window's (%x) icon data: (length: %v)\n", active, len(icons)) for _, icon := range icons { fmt.Printf("\t(%d, %d)", icon.Width, icon.Height) fmt.Printf(" :: %d == %d\n", icon.Width*icon.Height, len(icon.Data)) } work := icons[2] fmt.Printf("Working with (%d, %d)\n", work.Width, work.Height) width, height := int(work.Width), int(work.Height) mask := image.NewRGBA(image.Rect(0, 0, width, height)) img := image.NewRGBA(image.Rect(0, 0, width, height)) for x := 0; x < width; x++ { for y := 0; y < height; y++ { argb := work.Data[x+(y*height)] alpha := argb >> 24 red := ((alpha << 24) ^ argb) >> 16 green := (((alpha << 24) + (red << 16)) ^ argb) >> 8 blue := (((alpha << 24) + (red << 16) + (green << 8)) ^ argb) >> 0 c := color.RGBA{ R: uint8(red), G: uint8(green), B: uint8(blue), A: uint8(alpha), } img.SetRGBA(x, y, c) mask.Set(x, y, color.Alpha{uint8(alpha)}) } } // blendMask := image.NewUniform(color.Alpha{127}) // draw.DrawMask(mask, mask.Bounds(), mask, image.ZP, blendMask, // image.ZP, draw.Src) dest := image.NewRGBA(image.Rect(0, 0, width, height)) allBlue := image.NewUniform(color.RGBA{127, 127, 127, 255}) draw.Draw(dest, dest.Bounds(), allBlue, image.ZP, draw.Src) draw.DrawMask(dest, dest.Bounds(), img, image.ZP, mask, image.ZP, draw.Over) // Let's try to write some text... WriteText(dest) destWriter, err := os.Create("someicon.png") if err != nil { fmt.Print("could not create someicon.png") os.Exit(1) } png.Encode(destWriter, dest) // Let's see if we can paint the image we generated above to a window. win := X.Conn().NewId() gc := X.Conn().NewId() scrn := X.Conn().DefaultScreen() cursor := xcursor.CreateCursor(X, xcursor.Fleur) winMask := uint32(xgb.CWBackPixmap | xgb.CWOverrideRedirect | xgb.CWBackPixel | xgb.CWCursor) winVals := []uint32{xgb.BackPixmapParentRelative, scrn.BlackPixel, 1, uint32(cursor)} X.Conn().CreateWindow(scrn.RootDepth, win, X.RootWin(), 100, 400, uint16(width), uint16(height), 0, xgb.WindowClassInputOutput, scrn.RootVisual, winMask, winVals) X.Conn().CreateGC(gc, X.RootWin(), xgb.GCForeground, []uint32{scrn.WhitePixel}) X.Conn().MapWindow(win) // try paitning the image we created above... // First we have to transform the image into X format. (BGRA) // Then we have to allocate resources for the pixmap. // Then we can paint the pixmap. // Finally, we attach that pixmap as the "BackPixmap" of our window above. // (And free pixmap right thereafter, of course.) imgData := make([]byte, width*height*4) for x := 0; x < width; x++ { for y := 0; y < height; y++ { r, g, b, a := dest.At(x, y).RGBA() i := 4 * (x + (y * height)) imgData[i+0] = byte(b) imgData[i+1] = byte(g) imgData[i+2] = byte(r) imgData[i+3] = byte(a) } } pix := X.Conn().NewId() X.Conn().CreatePixmap(scrn.RootDepth, pix, X.RootWin(), uint16(width), uint16(height)) X.Conn().PutImage(xgb.ImageFormatZPixmap, pix, gc, uint16(width), uint16(height), 0, 0, 0, 24, imgData) X.Conn().ChangeWindowAttributes(win, uint32(xgb.CWBackPixmap), []uint32{uint32(pix)}) X.Conn().ClearArea(false, win, 0, 0, 0, 0) X.Conn().FreePixmap(pix) time.Sleep(20 * time.Second) }