How do I stop KDE from changing the alt-tab order of minimized windows? - kde-plasma

I'm on KDE Plasma 5.16.5 on Manjaro. When I use my keyboard shortcut to minimize a KDE window, I would like to be able to restore it by just pressing alt-tab, similar to when I alt-tab without minimizing.
What is a reasonable way to achieve this?
The primary use case I have for this is chat apps. People are often talking to me, but I'm also working. I want to "minimize" the chat app so that I don't see it, but I want to be able to alt-tab back to it without having to search for it at the end of the list. I can sometimes use Alt-Space, search for it, and find it in the windows, but this doesn't always seem to work (and it's not as embedded in my muscle memory).
I'm fairly open to alternative solutions. An alternative alt-tab interface, more similar to Mac/Windows (centered icons) would also be fine.

Here is the needed patch to Kwin to achieve this, build your version then use /usr/local/bin/kwin_x11 --replace to test it.
From 47d6ab59eb8914ddb0857382f2d42dff8bb11402 Mon Sep 17 00:00:00 2001
From: intika <intika#librefox.org>
Date: Tue, 5 May 2020 09:40:08 +0200
Subject: [PATCH] Patch behavior of ctrl+tab to act like mac and windows
---
focuschain.cpp | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/focuschain.cpp b/focuschain.cpp
index 229314968..b3912fba7 100644
--- a/focuschain.cpp
+++ b/focuschain.cpp
## -238,17 +238,17 ## AbstractClient *FocusChain::nextForDesktop(AbstractClient *reference, uint deskt
void FocusChain::makeFirstInChain(AbstractClient *client, Chain &chain)
{
chain.removeAll(client);
- if (client->isMinimized()) { // add it before the first minimized ...
- for (int i = chain.count()-1; i >= 0; --i) {
- if (chain.at(i)->isMinimized()) {
- chain.insert(i+1, client);
- return;
- }
- }
- chain.prepend(client); // ... or at end of chain
- } else {
+// if (client->isMinimized()) { // add it before the first minimized ...
+// for (int i = chain.count()-1; i >= 0; --i) {
+// if (chain.at(i)->isMinimized()) {
+// chain.insert(i+1, client);
+// return;
+// }
+// }
+// chain.prepend(client); // ... or at end of chain
+// } else {
chain.append(client);
- }
+// }
}
void FocusChain::makeLastInChain(AbstractClient *client, Chain &chain)

Related

Toggling LED through button (ESP32 FreeRTOS) + binary semaphore

I had already done several projects using simple freertos ideas: led, button. Implementing semaphores, queues or some interrupt. I can't run this simple code tough.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#define BLINK_GPIO 21 //2
#define BUTTON_GPIO 0
void task_blink(void *pvParameters);
void task_botao(void *pvParameters);
//void wd_off_task(void *pvParameters);
SemaphoreHandle_t sem_sinc;
void app_main(void)
{
gpio_pad_select_gpio(BLINK_GPIO); // Configura o pino como IO
gpio_set_direction(BLINK_GPIO,GPIO_MODE_OUTPUT); // Configura o IO como saida
gpio_pad_select_gpio(BUTTON_GPIO); // Configura o pino como IO
gpio_set_direction(BUTTON_GPIO,GPIO_MODE_INPUT); // Configura o IO como entrada
vSemaphoreCreateBinary(sem_sinc); // Cria o Semaforo
xSemaphoreTake(sem_sinc,0); // Garante que inicializa com 0
xTaskCreate(task_blink,"Task Blink",1024,NULL,2,NULL);
printf("Task Blink Criada!!!\r\n");
xTaskCreate(task_botao,"Task Botao",1024,NULL,2,NULL);
printf("Task Botao Criada!!!\r\n");
//xTaskCreate(wd_off_task,"Task desliga WD",1024,NULL,1,NULL);
}
void task_botao(void *pvParameters)
{
while(1)
{
if(gpio_get_level(BUTTON_GPIO) == 0)
{
while(gpio_get_level(BUTTON_GPIO) == 0){}
printf("Botao Pressionado!!!\r\n");
xSemaphoreGive(sem_sinc);
vTaskDelay(1);
}
}
}
void task_blink(void *pvParameters)
{
while(1)
{
if(xSemaphoreTake(sem_sinc,portMAX_DELAY)==pdTRUE)
{
printf("Pisca Led!!!\r\n");
if((gpio_get_level(BUTTON_GPIO) == 0))
gpio_set_level(BLINK_GPIO, 1);
else
gpio_set_level(BLINK_GPIO, 0);
}
}
}
The issue:
The code is built nicely, and the same for the flashing to ESP. As I press the button, it shows in the terminal the designed messages. See, the only problem here lies on I can't set the LED's level, toggling it! Because of this, all I can get is the LED turning on and turning off afterwards quickly(every time the semaphore syncronizes the 2 tasks).
I suspect it's all about some kind of config, related to this GPIO. (Although I'm using the reset port to read the button, I still think this is not the matter, because the port was properly configured on the lines above)
Your switch polling needs to detect transitions, but avoid erroneously detecting switch bounce as a valid transition. For example:
#define BUTTON_DN = 0 ;
#define BUTTON_UP = 1 ;
#define POLL_DELAY = 50 ;
void task_botao(void *pvParameters)
{
int button_state = gpio_get_level( BUTTON_GPIO ) ;
for(;;)
{
int input_state = gpio_get_level( BUTTON_GPIO ) ;
// If button pressed...
if( input_state == BUTTON_DN &&
button_state != BUTTON_UP )
{
button_state = BUTTON_DN ;
// Signal button press event.
xSemaphoreGive(sem_sinc ) ;
}
// otherwise if button released...
else if( input_state == BUTTON_UP &&
button_state != BUTTON_DN )
{
button_state = BUTTON_UP ;
}
// Delay to yield processor and
// avoid switch bounce on transitions
vTaskDelay( POLL_DELAY );
}
}
The blinking task need not be reading the button input at all; not is it unnecessary, it is also a bad design:
void task_blink(void *pvParameters)
{
int led_state = 0 ;
gpio_set_level( BLINK_GPIO, led_state ) ;
for(;;)
{
if( xSemaphoreTake( sem_sinc, portMAX_DELAY ) == pdTRUE )
{
led_state = !led_state ;
gpio_set_level( BLINK_GPIO, led_state ) ;
}
}
}
There are some things to consider. Your thinking is logical, but there are some issues.
A button is a mechanical device and while you press it, you think it will be a straightforward 0 instead of 1 it’s not. If you have an oscilloscope, I recommend you to check the voltage level on the gpio input. Or google button bounce. And floating pins. Those two concepts should be clear. The processor is very straightforward in interpreting the values.
Example: https://hackaday.com/wp-content/uploads/2015/11/debounce_bouncing.png
Now your functions are in fact constantly checking the button status, somehow at the cost of processor time. For small projects not of an issue, but when they get bigger they are.
What you want to do is to setup an interrupt to the button status: at the moment the level changes it will fire some code. And it doesn’t have to double check the gpio status in two tasks, with the chance it will miss the status in the second (because of delays). It’s important to realize you are checking the same level twice now.
Not a problem now but maybe later: the stack size of the tasks is somehow small, make it a good use to always check if it’s enough by checking the current free size. Vague problems arise if it’s not.

Detect if a Tcl script is run in a background process

I'm looking for a preferably cross-platform way to detect from within a Tcl script if the interpreter is running in a foreground or in a background process.
I've seen how to do it via ps (or /proc/$$/stat on Linux); is there a better way or do I have to hack something around that approach? I already have a utility library written in C so exposing the lowlevel API that ps also uses so I don't have to parse process output (or special file content) would be fine.
There's no truly cross-platform notion of foreground, but the main platforms do have ways of doing it according to the notion they have of foreground.
Linux, macOS, and other Unix:
For determining if a process is foreground or not, you need to check if its process group ID is the terminal's controlling process group ID. For Tcl, you'd be looking to surface the getpgrp() and tcgetpgrp() system calls (both POSIX). Tcl has no built-in exposure of either, so you're talking either a compiled extension (may I recommend Critcl for this?) or calling an external program like ps. Fortunately, if you use the latter (a reasonable option if this is just an occasional operation) you can typically condition the output so that you get just the information you want and need to do next to no parsing.
# Tested on macOS, but may work on other platforms
proc isForeground {{pid 0}} {
try {
lassign [exec ps -p [expr {$pid ? $pid : [pid]}] -o "pgid=,tpgid="] pgid tpgid
} on error {} {
return -code error "no such process"
}
# If tpgid is zero, the process is a daemon of some kind
expr {$pgid == $tpgid && $tpgid != 0}
}
Windows
There's code to do it, and the required calls are supported by the TWAPI extension so you don't need to make your own. (WARNING! I've not tested this!)
package require twapi_ui
proc isForeground {{pid 0}} {
set forground_pid [get_window_thread [get_foreground_window]]
return [expr {($pid ? $pid : [pid]) == $foreground_pid}]
}
Thanks to Donal I came up with the implementation below that should work on all POSIX Unix variants:
/*
processIsForeground
synopsis: processIsForeground
Returns true if the process is running in the foreground or false
if in the background.
*/
int IsProcessForegroundCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
/* Check the arg count */
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
int fd;
errno = 0;
if ((fd = open("/dev/tty", O_RDONLY)) != -1) {
const pid_t pgrp = getpgrp();
const pid_t tcpgrp = tcgetpgrp(fd);
if (pgrp != -1 && tcpgrp != -1) {
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pgrp == tcpgrp));
close(fd);
return TCL_OK;
}
close(fd);
}
Tcl_SetErrno(errno);
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "processIsForeground: ", (char *)Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
int Pextlib_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.4", 0) == NULL)
return TCL_ERROR;
// SNIP
Tcl_CreateObjCommand(interp, "processIsForeground", IsProcessForegroundCmd, NULL, NULL);
if (Tcl_PkgProvide(interp, "Pextlib", "1.0") != TCL_OK)
return TCL_ERROR;
return TCL_OK;
}

How to show choice in Game maker with gamepad functionality

I am working on a Dragon Warrior - type rpg game in Game Maker studio and can't figure out how to get a show choice option that doesn't use the mouse. I have setup the game to run completely with a gamepad, but when I am confronted with the situation that requires feedback (choice selection) from the player I am unable to get the gamepad working. Heres the GML
if (distance_to_object(obj_judy)) <= 64 {
if keyboard_check(vk_space) || gamepad_button_check_pressed(0, gp_face3) {
show_question(mine_crystal);
if true {
global.energy -= 10;
global.power_crystal += 1;
instance_destroy();
}
}
}
The problem is " show_question(); " uses a windows-type popup and doesn't work with the gamepad.
How do I get feedback from the player using only inputs from the gamepad?
Thanks for your time reading and your help with this small issue.
So yeah, you'll need to write that logic yourself. Also, that code you wrote there looks kinda scary, i'd use this;
if (show_question(mine_crystal) == true) {
global.energy -= 10;
global.power_crystal += 1;
instance_destroy();
}
because
show_question(mine_crystal);
if true {
global.energy -= 10;
global.power_crystal += 1;
instance_destroy();
}
Will show a question, and then always do the mine crystal action (because your if (true) will always evaluate to true, it doesn't know about the line above

Strange Errors in a For Loop

Hello there fellow coders.
I have been learning my way around GLKit over the past few weeks. I found this very helpful series of tutorials on how to set-up a basic 2D graphics engine found here.
When I followed the first chunk of 'Iteration 5' code something strange happened. The for loop in the updateVertices method comes up with compiler errors. Those errors are shown here.
Here's the class code in it's entirety.
//
// Elipse.m
// EmptyGLKit
//
// Created by C-R on 8/6/13.
// Copyright (c) 2013 C-R. All rights reserved.
//
#import "Ellipse.h"
#define ELLIPSE_RESOLUTION 64;
#define M_TAU (2*M_PI)
#implementation Ellipse
-(int)numVertices {
return ELLIPSE_RESOLUTION;
}
-(void)updateVertices {
for (int i = 0; i < ELLIPSE_RESOLUTION; i++) {
float theta = ((float)i) / ELLIPSE_RESOLUTION * M_TAU;
self.vertices[i] = GLKVector2Make(cos(theta)*radiusX, sin(theta)*radiusY);
}
}
-(float)radiusX {
return radiusX;
}
-(void)setRadiusX:(float)_radiusX {
radiusX = _radiusX;
[self updateVertices];
}
-(float)radiusY {
return radiusY;
}
-(void)setRadiusY:(float)_radiusY {
radiusY = _radiusY;
[self updateVertices];
}
#end
I've tried closing and reopening the project, cleaning the code, rebooting Xcode, all without success.
To my knowledge that for loop is completely acceptable and has been in several other projects of mine.
Your #define line has a ; at the end. This isn't correct and should be removed. The #define is basically substituted into the code for compilation so the end result is an if statement with too many ; characters in it.

iOS/Objective-C: library to connect to POP3

I'd like to connect to IMAP and POP3 servers, for IMAP I'm currently using MailCore. Unfortunately I don't find a suitable POP3-framwork.
I tried with libetpan:
mailpop3 * pop3;
int r;
pop3 = mailpop3_new(0, NULL);
r = mailpop3_ssl_connect(pop3, "pop.gmail.com", 995);
check_error(r, "connect failed");
but I always get a connection refused error; and it's only C, I would prefer Objective-C. Even better would be a library which I could use for both; IMAP and POP3.
I haven't used OCMail, but it seems like it's what you're looking for. It claims to support "POP3, IMAP4, SMTP, POPS, IMAPS, SMTPS".
Edit: Build Error
Turns out, the solution is actually in the README file.
Once you've downloaded the ZIP from Github, open the Xcode project.
Build for Profiling (Product Menu > Build For > Profiling (Command-Shift-I)).
Open Xcode preferences and go to "Locations"
Under Derived Data, next to the Advanced button you'll see a file path (something like /Users/YourUserName/Library/Developer/Xcode/DerivedData). There'll be a little arrow next to the path; click the arrow to go to that location in Finder.
It'll take you to a folder with all of your Xcode projects. Find the folder whose name starts with OCMail (and has a bunch of gibberish after it).
In that folder, find Build > Products > Debug-iphoneos > libOCMail.a. That's the library file you'll want to add into your Xcode project. Just drag it into your Xcode project and you should be good to go.
I got a bunch of errors building the project. They came from a badly defined enum type. Here's a cleaned up file:
http://cl.ly/code/442x2x3X3Y2I
Just download and replace the existing MimeMessage.m file before you build.
I was working with libetpan in past and I was connecting to pop3 server without problems, so I checked if it still working. I used code from here: https://github.com/dinhviethoa/libetpan/blob/master/tests/pop-sample.c and adjusted it for iOS.
If You use it, You will see a lot of warnings and app will crash after fetching first message, but connecting is working (of course, You need to enter Your email login and password).
I'm not saying that libetpan is good solution. When I was developing app with mail support I also used mailcore for IMAP and eventually resigned from POP3 support. But if You run from options it could be useful.
static void check_error(int r, char * msg)
{
if (r == MAILPOP3_NO_ERROR)
return;
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
-(IBAction)testButtonClick:(id)sender
{
mailpop3 * pop3;
int r;
carray * list;
unsigned int i;
// if (argc < 3) {
// fprintf(stderr, "syntax: pop-sample [gmail-email-address] [gmail- password]\n");
// exit(EXIT_FAILURE);
// }
mkdir("download", 0700);
pop3 = mailpop3_new(0, NULL);
r = mailpop3_ssl_connect(pop3, "pop.gmail.com", 995);
check_error(r, "connect failed");
r = mailpop3_user(pop3, #"mail login".cString);
check_error(r, "user failed");
r = mailpop3_pass(pop3, #"mail password".cString);
check_error(r, "pass failed");
r = mailpop3_list(pop3, &list);
check_error(r, "list failed");
NSLog(#"carray_count(list_: %d", carray_count(list));
for(i = 0 ; i < carray_count(list) ; i ++) {
struct mailpop3_msg_info * info;
char * msg_content;
size_t msg_size;
FILE * f;
char filename[512];
struct stat stat_info;
info = (mailpop3_msg_info *) carray_get(list, i);
if (info->msg_uidl == NULL) {
continue;
}
snprintf(filename, sizeof(filename), "download/%s.eml", info->msg_uidl);
r = stat(filename, &stat_info);
if (r == 0) {
printf("already fetched %u %s\n", info->msg_index, info->msg_uidl);
continue;
}
if(msg_content != NULL)
NSLog(#"msg_content: %#", [NSString stringWithUTF8String:msg_content]);
r = mailpop3_retr(pop3, info->msg_index, &msg_content, &msg_size);
check_error(r, "get failed");
// f = fopen(filename, "w");
// fwrite(msg_content, 1, msg_size, f);
// fclose(f);
// mailpop3_retr_free(msg_content);
if (info->msg_uidl != NULL) {
printf("fetched %u %s\n", info->msg_index, info->msg_uidl);
}
else {
printf("fetched %u\n", info->msg_index);
}
}
mailpop3_quit(pop3);
mailpop3_free(pop3);
// exit(EXIT_SUCCESS);
}