Writing a compositing window manager with python and xlib - python

I'm writing a simple window manager as a hobby project, and I've chosen python and xlib to implement it. I'd like to have some fancy effects like windows sliding from left and right, and from what I've been able to dig up, the best way to go about this is to use the composite extension to render windows to offscreen buffers, and then manipulate those buffers and paint them however I want.
However, with python-xlib documentation somewhat lacking, I found no way to do this, and I haven't found any examples of using python-xlib with the composite extension. Where can I find this information, and has anyone used python-xlib with composite?
I suppose I could always switch to xcb which seems to support composite for python, but I'd prefer not having to rewrite the whole thing and figure out a different API with somewhat lacking python documentation.
To summarize, my questions are:
Is there a way to use composite with python-xlib?
Would it be a better idea to switch to xcb for this?
Any additional suggestions and advice are welcome.

Yes, there is support for Composite extension in python-xlib. Take a look at extension client implementation You'll probably need composite_redirect_window and composite_name_window_pixmap

Related

Python: creating a new window, accessing it's pixels and activating them

I have been thoroughly searching this forum, the internet, and pretty much everything. I want to be able to create a new graphics window in python without using something else, for a project in which I want specialized optimized for whatever a need without any other extra mumbo-jumbo, and understanding fully how it works. Anyways, I want to be able to access pixel by pixel of a new window without using tkinter/turtle, installations, or anything of the sort. Just basic, simple, pixel access of a new window. If this isn't possible, just let me know. I imagine the program could look something like this:
import NOTHING_AT_ALL_GRAPHICS_WISE
window.pixel(1,2,True)
I program in Python 3.6.3
What you seek to accomplish isn't as simple as you might believe. Applications draw graphics on the screen largely with the help of calls to the graphics card API. Those API's can be complicated, as they should be, because all the graphics that you see on your screen, whether it be your browser GUI, to video playback, to your Starcraft II, has to use combinations of these calls to produce the beautiful and seamless graphics you see on your screen (graphics would NOT look good without use of the GPU).
However, not all manipulation of graphics has to be so complicated, and many languages/frameworks write wrappers around some of the graphics libraries that expose a simpler subset of the total functionality. Tkinter is a good example.
If you don't want to import ANYTHING, you will have to make the calls to the API yourself, and you're not in for a good time. Nobody does this nowadays for personal projects because it really is quite complicated. Also, Python is a very high-level language, and although it might expose the OS's system calls that you need, you're probably better off doing it in C. Before you proceed, I suggest you read up on the fundamentals of computer graphics work. Here's a nice image that shows how OpenGL, a very popular graphics library, works.
There is no way to do what you want. Python has no way of changing a single pixel on the screen. This is the whole reason why such "mumbo jumbo" libraries exist: it's a complex problem that requires specialized libraries that know how each operating system works.

Is there a preferred framework for non-standard, non-native kiosk style GUI applications?

I've been toying with wxPython, but it seems mostly geared at 'standard' applications -- things with native looking file menu systems and toolbars and whatnot.
My needs are pretty simple. I just need to be able play some mp3s, show some images, and be able to package it down to an .exe and .dmg. Also, being able to play an small mp4 would be grand.
Unfortunately, I realize that there is no definitive answer to this question, and therefore doesn't exacltly fit the stack overflow format, but a nudge in the right direction would be greatly appreciated!
Pyqt/pyside/Qt has the newer declarative QML which seems to have a application geared to a kiosk type interface. You can basically design something in Photoshop and use it as your custom UI
Pygame is the usual choice for fully custom UIs.

Is there a way to access hardware directly in Python?

I want to learn about graphical libraries by myself and toy with them a bit. I built a small program that defines lines and shapes as lists of pixels, but I cannot find a way to access the screen directly so that I can display the points on the screen without any intermediate.
What I mean is that I do not want to use any prebuilt graphical library such as gnome, cocoa, etc. I usually use Python to code and my program uses Python, but I can also code and integrate C modules with it.
I am aware that accessing the screen hardware directly takes away the multiplatform side of Python, but I disregard it for the sake of learning. So: is there any way to access the hardware directly in Python, and if so, what is it?
No, Python isn't the best choice for this type of raw hardware access to the video card. I would recommend writing C in DOS. Well, actually, I don't recommend it. It's a horrible thing to do. But, it's how I learned to do it, and it's probably about as friendly as you are going to get for accessing hardware directly without any intermediate.
I say DOS rather than Linux or NT because neither of those will give you direct access to the video hardware without writing a driver. That means having to learn the whole driver API, and you need to invoke a lot of "magic," that won't be very obvious because writing a video driver in Windows NT is fairly complicated.
I say C rather than Python because it gives you real pointers, and the ability to do stupid things with them. Under DOS, you can write to arbitrary physical memory addresses in C, which seems to be what you want. Trying to get Python working at all under an OS terrible enough to allow you direct hardware access would be a frustration in itself, even if you only wanted to do simple stuff that Python is good at.
And, as others have said, don't expect to use anything that you learn with this project in the real world. It may be interesting, but if you tried to write a real application in this way, you'd promptly be shot by whoever would have to maintain your code.
This seems a great self-learning path and I would add my two-cents worth and suggest you consider looking at the GObject, Cairo and Pygame modules some time.
The Python GObject module may be at a higher level than your current interest, but it enables pixel level drawing with Cairo (see the home page) as well as providing a general base for portable GUI apps using Python
Pygame also has pixel level methods as well as access methods to the graphics drivers (at the higher level) - here is a quick code example
This is rather an old thread now, but I stumbled upon it while musing the same question.
I used to program in assembly language. In my day, drawing on screen was simply(?) a matter of poking a value into a memory location. The value turned a pixel on or off and defined its colour.
The term 'poke' comes from Basic by the way, not assembler. In assembler, you had to write a value into a data register then tell the processor where to put the data using another command and specifying an address register, usually in hexadecimal form! And each different processor had its own assembly language. But hec was the code fast!
As hardware progressed, I found that graphics hardware programming became more and more complex. There's much more to it than now simply defining a pixel. The graphics subsystem has its own processor -- or processors -- and it's that that you've got to learn to talk to. The processor doesn't just plonk stuff in memory locations. (I believe that what used to be the fastest supercomputer in the world for a while ran on graphics chips!) 'Plonk' is not a Basic command by the way.
Sorry; I digress. In answer to the original poster's query, I believe that the goal of understanding the graphics-drawing process could have been best achieved by experimenting with a Raspberry Pi. It's Python compatible and hence perfect for the job. Its hardware is well documented and it's cheap and easy to use.
Hope this helps someone, Cheers, M

PyQT vs PyObjc / Cocoa-Python

I'm thinking about developing an app for OS X using Python. I don't know Objective C and don't want to learn it right now.
I know and like Python. I'm trying to determine what GUI toolkit to use. I already have a bit of experience with PyQT, but not much. I've also seen that PyObjc or Cocoa-Python seem to allow use of Cocoa UI components from Python.
I'm curious if anyone has any input on how PyObjC stacks up to PyQT. I would be giving up cross platform abilities and I am not sure what I would be gaining.
I'm leaning towards PyQT right now, but wanted to see what you all thought. My big dislike of PyQT is having to pass around strings for the signals and slots. Is PyObjC similar?
If the only thing stopping you using PyQt is passing strings in signals, then the latest syntax should make your choice much easier. The old syntax (which can still be used) looks like this:
self.connect(self.action, SIGNAL('triggered()'), self.handler)
But the new style signals are much more pythonic:
self.action.triggered.connect(self.handler)

WxPython differences between Windows and Linux

The tutorials I've found on WxPython all use examples from Linux, but there seem to be differences in some details.
For example, in Windows a Panel behind the widgets is mandatory to show the background properly. Additionally, some examples that look fine in the tutorials don't work in my computer.
So, do you know what important differences are there, or maybe a good tutorial that is focused on Windows?
EDIT: I just remembered this: Does anybody know why when subclassing wx.App an OnInit() method is required, rather than the more logical __init__()?
I've noticed odd peculiarities in a small GUI I wrote a while back, but it's been a long time since I tried to the specifics are a rather distant memory. Do you have some specific examples which fail? Maybe we can improve them and fix the bugs?
Have you tried the official wxPython tutorials? ...or were you after something more specific?
r.e. your edit - You should use OnInit() because you're subclassing wx.App (i.e. it's a requirement for wxWidgets rather than Python) and the wxPython implementation is wherever possible, just a wrapper for wxWidgets.
[Edit] Zetcode has a fairly lengthy tutorial on wxPython. I've not looked through it all myself, but it might be of some help?
The wxWidgets::wxApp::OnInit() documentation is fairly clear:
This must be provided by the application, and will usually create the application's main window, optionally calling wxApp::SetTopWindow. You may use OnExit to clean up anything initialized here, provided that the function returns true.
If wxWidgets didn't provide a common interface then you'd have to do different things in C++ (using a constructor) compared to Python's __init__(self,...). Using a language-independent on-initialisation allows wxWidgets ports to other languages look more alike which should be a good thing right? :-)
EDIT: I just remembered this: Does anybody know why when subclassing wx.App an OnInit() method is required, rather than the more logical __init__()?
I use OnInit() for symmetry: there's also an OnExit() method.
Edit: I may be wrong, but I don't think using OnInit() is required.
I find a number of small differences, but don't remember all of them. Here are two:
1) The layout can be slightly different, for example, causing things to not completely fit in the window in one OS when the do in the other. I haven't investigated the reasons for this, but it happens most often when I use positions rather than sizers to arrange things.
2) I have to explicitly call Refresh more in Windows. For example, if you place one panel over another, you won't see it the top panel in Windows until you call Refresh.
I general, I write apps in Linux and run them in Windows, and things work similarly enough so this is a reasonable approach, but it's rare for me when something runs perfectly straight out of the gate after an OS switch.

Categories