Archive for the 'Trucos' Category

Un pasito p’alante María, y uno p’atrás

viernes, octubre 11th, 2019

Hace cosa de un mes se publicó la versión 3.34 de Gnome Shell, la cual incorporaba muchas mejoras internas de rendimiento. Por desgracia, también incorporaba tantos cambios internos que un amplio porcentaje de extensiones no funcionan con ella. Esto era algo de lo que ya nos habíamos olvidado, pues desde hace unas cuantas versiones no había cambios de arquitectura internos tan grandes que afectasen de esta manera a las extensiones. Aunque tuve suerte con ActivityAppLauncher y con Desktop Icons NG (pues ambas funcionan perfectamente sin ningún cambio), no la hubo con la extensión Desktop Icons original, principalmente por culpa del nuevo sistema de herencia en clases Javascript, que, al permitir heredar desde clases de GObject, ya no obliga a meter un actor St en una propiedad de una clase, sino que la clase en sí puede heredar directamente de ella.

Afortunadamente, Marco Trevisan se encargó de subir un parche que corregía este problema; sin embargo, para poder garantizar que funcionaba correctamente tuve que esperar a que Debian Sid actualizase Gnome Shell desde 3.30 a 3.34, cosa que ocurrió hace casi dos semanas. Tras unas cuantas pruebas del código procedí a empaquetarlo y subirlo. Alegría, alboroto, labor cumplida, bla bla bla…

Hasta que empiezan a llegar los avisos de bugs. En concreto, había uno muy grave, que rompía completamente el escritorio cada vez que se intentaba renombrar un icono. Ante semejante problema, tuve que poner en cuarentena rápidamente la nueva versión de la extensión y empezar a trabajar en el parche. Desgraciadamente, no conseguía avanzar: todo lo que intentaba seguía fallando de manera misteriosa. Afortunadamente, una vez más Marco Trevisan se puso manos a la obra y subió otro parche que corregía este problema y, de paso, actualizaba la forma del cuadro de diálogo para renombrar ficheros, haciéndola más consistente con Nautilus (nunca le podré estar lo suficientemente agradecido).

Ya puestos, aproveché para pedirle que revisase un parche mío que llevaba tiempo esperando ser aplicado: uno que corregía el tamaño de los thumbnails. Finalmente se pudo aplicar a tiempo, por lo que es posible que los usuarios de Ubuntu 19.10 puedan disfrutarla «de serie».

Pero los problemas no se acabaron ahí, pues surgieron dos bugs extra que afectaban, esta vez sí, a Desktop Icons NG. El primero es que, por un error en Mutter, el gestor de ventanas de Gnome Shell, el drag and drop desde el escritorio hacia una ventana de Nautilus deja de funcionar, cuando en Gnome Shell 3.30 y 3.32 siempre funcionó perfectamente. Tras mucho esfuerzo conseguí encontrar el parche concreto en el que se introdujo el error, y lo reporté. EDITO: ya lo han corregido. ¡Genial!

El segundo problema era más grave, pues por un bug en Gnome Shell en sí, crear una ventana de tipo DESKTOP con Gnome Shell trabajando en X.org (no se en Wayland, pues actualmente no se puede), rompía el modo de Actividades: era entrar en él y el escritorio se quedaba tonto. Afortunadamente lo resolvieron a tiempo para la versión 3.34.1, que salió hace cuatro días, por lo que ya no es un problema

Por lo tanto, si estás utilizando Gnome Desktop y Gnome Shell 3.34.0, te recomiendo que actualices de inmediato a Gnome Shell 3.34.1, para asegurarse de que mis extensiones trabajen lo mejor posible.

Desktop icons, Gnome shell y Wayland

viernes, septiembre 20th, 2019

Hace cosa de un año y medio la gente de Gnome anunció que eliminaba de Nautilus todo el código que pintaba los iconos de escritorio. Para los que no se quieran leer el tocho, resumiré rápidamente que el motivo era, básicamente, que dicho código venía de muchos años atrás, era extremadamente complejo debido a las limitaciones de las versiones antiguas de GTK, y cada vez era más difícil de mantener a la vez que se añadían nuevas características al resto de Nautilus. Además, hacía ya seis años que Gnome 3 no utilizaba iconos de escritorio. Por si fuera poco, tenía muchos bugs de difícil solución (por ejemplo, el soporte multimonitor no funcionaba demasiado bien). Y a todo esto había que sumar el hecho de que en Wayland no funcionaría correctamente debido a las limitaciones que impone en aras de la seguridad: en efecto, en Wayland una aplicación no puede decidir donde colocar una ventana ni mantenerla fija en el fondo, entre otras cosas. El motivo de esta limitación es evitar que una aplicación maliciosa pueda hacerse pasar, por ejemplo, por el escritorio, o por una barra de tareas, etc, poniendo en riesgo la seguridad del sistema. Por desgracia, esto también significa que, en Wayland, cosas como las barras del escritorio, un dock o los iconos de escritorio no se pueden delegar en una aplicación, sino que tienen que ser manejadas desde dentro del gestor de ventanas. Es por esto que se creó la extensión de Gnome Shell llamada Desktop Icons: para seguir ofreciendo iconos en el escritorio en Gnome Shell para aquellos que lo deseasen (como yo).

La versión disponible en aquel momento ya implementaba la funcionalidad más básica, pero tenía un defecto que, para mí, era muy grave: no permitía utilizar una única pulsación para lanzar un icono, sino que obligaba a utilizar doble click. Como yo estoy acostumbrado a la primera manera, me lié la manta a la cabeza y envié un parche para implementarlo. Tras muchos cambios para adecuar el estilo de código al que se utiliza en el proyecto Gnome y más cosas (nunca podré agradecer lo suficiente a Carlos Soriano su infinita paciencia enseñándome a manejar Git en condiciones), lo aprobaron. Y le cogí el gustillo, con lo que detrás de él vino otro, y otro, y otro más… Hasta que, recientemente, me ofrecieron ser el mantenedor del código (lo que para mí es un honor, todo sea dicho).

Un año después, la extensión ya incorpora todo lo que se pretendía para la versión 1.0 y más, y se incluye por defecto en la versión de Gnome Shell de Ubuntu, y no puedo menos que agradecer a toda la gente que ha colaborado con parches e informes de bugs.

Por desgracia, a medida que más y más usuarios la han ido instalando, han ido surgiendo algunos problemas inherentes al hecho de que sea una extensión, problemas que no eran nada evidentes al principio y que sólo se han ido haciendo visibles a medida que la cantidad de usuarios crecía.

El primer gran problema es que todas las extensiones se ejecutan en el mismo bucle principal que el compositor de ventanas. Esto significa que una extensión que necesite mucho tiempo para ejecutar una operación puede, literalmente, congelar todo el escritorio, incluyendo el mismísimo repintado de todas las ventanas. En el caso de extensiones «normales», que se limiten a mostrar un icono en la barra de tareas o así, esto no es un problema, porque el trabajo que realizan es mínimo; sin embargo, en el caso de Desktop Icons sí lo es, pues cada vez que tiene que refrescar el escritorio (por ejemplo porque se añade o borra un fichero), tarda en torno a medio segundo en realizar todas las operaciones (leer la lista de ficheros en el directorio, obtener sus metadatos, generar los pixmaps, eliminar las cuadrículas e iconos previos, generar una nueva cuadrícula, crear los nuevos iconos, y pintarlos en su sitio), y durante ese tiempo todo el escritorio se congela. Obviamente, por que ocurra una vez cada mucho no es muy problemático, pero sin duda es molesto para el usuario.

Solucionar esto, aunque no es totalmente imposible, no resulta sencillo: actualmente ya utilizamos funciones asíncronas en todos los sitios posibles para evitar bloquear la cola de eventos, pero no es suficiente. Además sería necesario evitar repintar todo el escritorio y sus elementos, y sólo añadir o quitar los iconos de los ficheros que se hayan añadido o eliminado. Pese a todo, esto sólo reduciría un poco más el problema, pero no lo resolvería del todo, pues si un programa añade y borra constantemente un fichero al escritorio, por ejemplo, puede aún bloquear la cola, en buena medida porque algunas operaciones de repintado se realizan sólo cuando ya no quedan operaciones pendientes en la cola de eventos. Además, implementar esto implicaría un importante rediseño interno, y teniendo en cuenta que algunas distribuciones cuentan con Desktop Icons para sus versiones de soporte a largo plazo, no es algo que se pueda hacer de cualquier manera, sino que debe implementarse de manera muy progresiva y con una buena revisión por pares de todos y cada uno de los parches, para garantizar que no hay errores ni regresiones.

Otro problema es la imposibilidad (al menos actualmente) de integrar Drag’n’Drop al completo: aunque dentro de Gnome Shell existe soporte de Drag’n’Drop, no es compatible con operaciones desde el «espacio de usuario»; esto es: una aplicación no puede ni enviar al compositor, ni recibir de él, eventos de Drag’n’Drop . Aunque en principio sería posible implementar dicha comunicación, no es una tarea trivial, y de hecho, tras tantear a algún programador de Mutter, la conclusión es que es lo suficientemente complicado como para que sólo valga la pena pasar el trabajo de implementarlo en Wayland, pero no en X11.

Y de aquí llegamos al tercer problema: las extensiones se escriben con Clutter + St, los cuales no funcionan exactamente igual que Gtk. Un ejemplo es la forma en que se procesan los eventos de enter_notify y exit_notify, que obligó a añadir una serie de trucos en el código que permite seleccionar un grupo de iconos mediante «goma elástica», para gestionar correctamente aquellos casos en los que el cursor entraba en una ventana en mitad de una selección, o cuando pasaba por encima de la barra superior de Gnome. Esto es algo que en Gtk está resuelto desde hace años, gracias al mayor número de usuarios y programadores que trabajan con él, y que permite detectar más bugs.

El cuarto problema radica en los cambios entre versiones del escritorio. Dado que Gnome Shell no ofrece una API estable para las extensiones, éstas tienen que interactuar directamente con el código interno, por lo que cualquier cambio les puede afectar. En el caso de una extensión tan compleja como Desktop Icons este problema es aún mayor, hasta el punto de que la actual versión 19.01 será, probablemente, la última compatible con Gnome Shell 3.30 y 3.32, y las nuevas versiones necesitarán como mínimo Gnome Shell 3.34.

A la vista de todos estos problemas, hace un par de meses empecé a sopesar la posibilidad de hacer un cambio radical en el diseño y mover toda la lógica a un proceso independiente del compositor, de manera que toda la gestión de los iconos del escritorio se realice sin interferir con la composición y demás, además de utilizar Gtk directamente en lugar de St y Clutter. De hecho, cuando se decidió crear la extensión, los autores originales (Carlos Soriano y Ernestas Kulik) sopesaron seriamente esta misma posibilidad, pero lo descartaron precisamente por las limitaciones impuestas por el modelo de seguridad de Wayland, y porque hacerlo dentro de una extensión tenía más sentido en aquel momento, pues era muchísimo más fácil.

Por supuesto, esto es más sencillo de decir que de hacer, pues, como ya dije antes, aunque en X11 no hay ningún problema en que una aplicación mantenga una ventana en el fondo, o que la elimine de la lista de ventanas para que no aparezca al hacer Alt + Tab, en Wayland eso es totalmente imposible por diseño. Además, dado que las extensiones están escritas en Javascript, no es posible lanzar código en un nuevo thread, y aunque se pudiese, no sería posible que dicho código llamase a funciones de Clutter o St, por lo que hay que descartar la idea de descargar el trabajo en un thread paralelo. Lanzar un proceso independiente sí es posible, pero éste trabajaría desde fuera del compositor, por lo que, en principio, seguiríamos con el mismo problema.

Sin embargo, existe una alternativa extra, que es justo la que decidí investigar, que consiste en repartir el trabajo: por una parte tenemos un programa normal, que trabaja desde fuera del compositor y que utiliza GTK para gestionar absolutamente todo lo relacionado con el escritorio y sus iconos mediante una o varias ventanas normales, exactamente igual a como hacía el viejo Nautilus en el modo «iconos de escritorio»; y, por otro lado, una pequeña extensión cuyo trabajo consiste en lanzar el programa anterior (y relanzarlo cada vez que se muera), detectar la ventana que abre, y asegurarse de que ésta se mantenga donde debe. De esta manera, el código dentro de la extensión es mínimo y se limita exclusivamente a las operaciones que son imposibles de realizar desde el exterior del código del compositor.

Por supuesto, es fundamental no romper el modelo de seguridad de Wayland, lo que significa que no se puede permitir bajo ningún concepto que una aplicación extraña se pueda aprovechar de este mecanismo para colocar su propia ventana como el fondo del escritorio (o como cualquier otro elemento). Para ello, la única solución es que sea la extensión quien lance el proceso, y que cada vez que aparezca una ventana, compruebe si ésta pertenece al proceso que ella misma ha lanzado, otorgándole esos privilegios exclusivamente en el caso de que así sea. Dado que el código ha sido lanzado específicamente por la extensión, se puede considerar que es código tan confiable como el de dicha extensión (y más si el programa a lanzar forma parte de la propia extensión): si un programa malicioso puede reemplazar el código de la aplicación de escritorio, también podría hacerlo directamente con el código de la extensión, por lo que el nivel de seguridad es exactamente el mismo.

Ahora llega la cuestión de cómo detectar que una ventana pertenece al proceso lanzado desde la extensión. Mi primera idea fue utilizar metawindow_get_pid() en cada ventana nueva que apareciese, para obtener el PID del proceso que creó la ventana y compararlo con el PID del proceso que hemos lanzado desde la extensión; por desgracia, dicha llamada sólo funciona en X11 pero no en Wayland, porque utiliza un dato específico de X11. Sin embargo, existe otra llamada, metawindow_get_client_pid(), que sí funciona desde ambos sistemas; por desgracia es privada, lo que significa que sólo se puede llamar desde C y desde dentro de mutter, nunca desde una extensión escrita en Javascript.

Propuse entonces en el canal IRC de Gnome Shell que dicha llamada se cambiase a pública, pero mi idea no convenció porque existen varios ataques que involucran PIDs de procesos, por lo que, aunque yo hiciese las cosas bien, hacer pública dicha llamada podría suponer abrir la caja de Pandora. Sin embargo, sí me redirigieron al código de XWayland para que viese ahí como lo hacen de manera segura: básicamente, al lanzar el proceso crean manualmente un socket y asignan un extremo a Wayland, pasando el otro extremo al proceso hijo para que se comunique a través de él; luego basta con engancharnos a la señal map() y, por cada ventana que aparezca, comparar si su socket coincide con el que creamos nosotros para nuestro proceso hijo, en cuyo caso podemos estar seguros de que esa ventana pertenece a él y no a otro.

La idea era buena, pero por desgracia no se puede implementar directamente en Javascript porque precisa de varias llamadas privadas de mutter, además de que tampoco se pueden crear sockets desde Javascript. Ante esto me sugirieron escribir una clase GObject que lo implementase y exportase una interfaz para ello, y así lo hice: mi primer parche para mutter y mi primera clase GObject. Esta clase sólo funciona con Wayland (para X11 no tiene sentido, pues la propia aplicación puede detectarlo y hacer ella misma el trabajo), y permite lanzar un proceso y detectar si una ventana concreta pertenece o no a dicho proceso. Si se utiliza desde X11, la parte de lanzar el proceso también funciona, pero el método de detectar si una ventana pertenece o no al proceso genera una excepción (que, obviamente, se puede capturar). Esto permite simplificar el código en la extensión a la hora de hacer que funcione en ambos entornos de ventanas.

Aunque dicho parche funciona bien, aún sigue pendiente de aprobación; pero yo quería poder usar YA la nueva versión de Desktop Icons, así que, como a cabezón no me gana nadie, decidí ver qué podía hacer para detectar de manera segura la ventana de un proceso utilizando sólo lo que ya tenía disponible en Javascript. Para ello se me ocurrió que la aplicación de escritorio podría poner como título de la ventana una cadena concreta que la extensión pudiese identificar (tiene que ser en el título, pues no parece haber absolutamente nada más en una ventana que se pueda asignar de manera libre por el programa y que una extensión pueda leer). El problema es que dicha cadena no puede ser predecible, pues entonces otras aplicaciones podrían hacerse pasar por la legítima. Ante esto, decidí que la extensión generaría un UUID aleatorio de 128 bits justo antes de lanzar el proceso, y se lo pasaría a éste para que lo ponga en el título de la ventana (y, por supuesto, calculando uno nuevo cada vez que la aplicación se muera). Pero claro, pasarlo como parámetro por la línea de comandos sería completamente inseguro porque cualquier programa puede leer los parámetros de cualquier otro proceso (basta hacer un ps ax o leer /proc), por lo que tenía que ser algo más seguro. Al final la solución consistió en pasarlo a través de stdin, de manera que nadie más pueda leerlo (habría sido más elegante utilizar un pipe específico, pero por desgracia desde Javascript no es posible crear nuevos pipes).

Para simplificar aún más el código escribí una pequeña clase Javascript que es compatible a nivel de métodos con la clase GObject de mi parche, de manera que, si se aprueba, sólo tendré que reemplazar una clase por otra en el código (o incluso utilizar una u otra en función de la versión de Gnome Shell).

Con esto resolví el primer problema, pero ahora quedaba el segundo: aunque ya puedo identificar qué ventana es la del escritorio ¿como hago para mantenerla donde debe estar?

La solución elegante sería cambiar el tipo de ventana a uno de los tipos estándar (en concreto, a META_WINDOW_DESKTOP). Por desgracia, desde Javascript no es posible cambiarlo, pues la llamada es privada. Obviamente preparé un parche para cambiarlo, donde, además de hacerla pública, también la renombro para que sea consistente. Este cambio convenció mucho más en el canal IRC, por lo que espero que sea finalmente aceptado junto con el otro, pues la ventaja de estos dos parches es que no son específicos para este proyecto, sino que permiten, en general, «externalizar» el trabajo que actualmente se realiza dentro del compositor, lo que permitiría que más elementos, como por ejemplo la barra superior o un dock, puedan ser gestionados desde un proceso externo.

Sin embargo, seguía queriendo poder utilizar YA el programa, así que lo que hice fue engancharme a varias señales para forzar la ventana a permanecer en su sitio:

  • raised: esta señal se emite cada vez que una ventana pasa a primer plano. En su callback llamo al método lower(), que se encarga de mandarla debajo de todas las demás ventanas, manteniéndola así al fondo.
  • position-changed: como su nombre indica, esta señal se emite cuando el usuario cambia la posición de una ventana. En el callback la devuelvo siempre a donde le corresponde. Y es que, aunque la ventana del escritorio no está decorada (y, por tanto, en principio el usuario no tendría donde pinchar para moverla), sigue siendo posible utilizar combinaciones de teclas para cambiarla de sitio, cosa que no se puede permitir.

A mayores llamo a stick() para que la ventana aparezca en todos los workspaces.

Con esto ya se puede conseguir que la ventana permanezca siempre en su sitio, pero aún queda por evitar que aparezca en la lista de ventanas. De no hacerlo, aparecerá en el modo Actividades de Gnome Shell y en el cambiador de ventanas (el de Alt + Tab). Para solucionar esto hay que reemplazar tres métodos:

  • Meta.Display.get_tab_list()
  • Shell.Global.get_window_actors()
  • Meta.Workspace.list_windows()

Con estos tres métodos, la ventana desaparece «lo suficiente» como para que sea usable (por ejemplo, en Dash to Dock no desaparece, pero es un mal menor). Por supuesto no es muy elegante, y el resultado será perfecto si se acepta el parche para cambiar el tipo de ventana.

Y de esta manera tan horrorosa (aunque sólo hasta que aprueben mis parches… si es que los aprueban, claro) conseguí mover toda la funcionalidad del escritorio fuera del compositor, lo que resuelve de un plumazo todos los problemas anteriores. El resto del trabajo fue, básicamente, convertir los widgets de St y Clutter en los equivalentes de Gtk, quitar mucho código asíncrono que ya no era necesario y sólo complicaba terriblemente la lógica, y algunos detalles a mayores como añadir código extra en la extensión para que, durante el arranque, le comunique cuantos monitores hay, así como sus coordenadas y tamaños.

La extensión ya está disponible en la página de extensiones de Gnome Shell, y ofrece, además de todo lo que ya tiene la extensión original, Drag’n’Drop, no congelar la composición del entorno gráfico cuando se refresca el escritorio, más velocidad, mostrar los nombres de ficheros demasiado largos cuando se pase por encima el ratón, y más.

Ventana transparente en Gtk 3 y Javascript

sábado, agosto 17th, 2019

Hacer una ventana con el fondo transparente utilizando Gtk es un clásico; de hecho hay ejemplos de como hacerlo en python, en C y en Vala. Pero falta como hacerlo con Javascript, y dado que es el lenguaje de moda para Gnome (y también por una serie de circunstancias extra) me he decidido a hacer el ejemplo. Este es el código:

#!/usr/bin/env gjs

imports.gi.versions.Gtk = '3.0';
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;

Gtk.init(null);

let window = new Gtk.Window();
window.set_app_paintable(true);
let screen = window.get_screen();
let visual = screen.get_rgba_visual();
if (visual && screen.is_composited()) {
    window.set_visual(visual);
    window.connect('draw', (widget, cr) => {
        Gdk.cairo_set_source_rgba(cr, new Gdk.RGBA({red: 0.0,
                                                    green: 0.0,
                                                    blue: 0.0,
                                                    alpha: 0.0}));
        cr.paint();
        return false;
    });
    window.connect('delete-event', () => {
        Gtk.main_quit();
    });
    window.show_all();
    Gtk.main();
} else {
    print("El entorno de ventanas no admite transparencia");
}

Aunque el código no tiene nada de especial comparado con las versiones en otros lenguajes, sí es cierto que tuve problemas con Gdk.cairo_set_source_rgba, pues, como se ve, no sigue la estructura «normal» de llamadas como si fuera un objeto, sino que sigue el formato de C. Lo lógico sería hacer cr.cairo_set_source_rgba(…), pero no funciona. Y lo mismo con algunas otras.

Múltiples archivos en aplicaciones Gtk con Javascript

viernes, mayo 24th, 2019

Desde hace unos meses estoy colaborando como desarrollador con Carlos Soriano, echándole una mano con Desktop Icons, la extensión para Gnome Shell que escribió para devolver los iconos al escritorio tras retirar dicho soporte de Nautilus.

Como muchos sabrán ya, las extensiones, al igual que el resto de Gnome Shell, están escritas en Javascript, y además no utilizan Gtk sino Clutter/St. Sin embargo, Javascript también se puede utilizar para escribir aplicaciones normales, de escritorio, con Gtk de toda la vida. Para ello basta con utilizar el shebang #!/usr/bin/gjs al principio del archivo. Personalmente sigo prefiriendo Python, pero obviamente para gustos hay colores.

Y precisamente aquí me encontré con el primer gran problema: estoy intentando portar parte de una extensión a espacio de usuario, y dado que el código de la extensión está repartido en varios archivos, quería mantenerlo así también en la aplicación. Por desgracia, por más que buscaba no encontraba como resolver el problema, pues aunque existen algunas aplicaciones Gtk en Javascript que ocupaban varios archivos, no tenía muy claro cómo hacían para que, al llamar a imports, la máquina virtual encontrase el fichero. Pero por fin, después de buscar y rebuscar, encontré la clave:

imports.searchPath.unshift(ruta_donde_buscar_ficheros);

Esa llamada recibe como parámetro un string donde podemos añadir una ruta extra donde debe buscar ficheros. Basta con que pongamos la carpeta donde se encuentran el resto de ficheros .js de nuestro proyecto, y el comando imports los encontrará igual que encuentra los ficheros del sistema. Por supuesto es necesario añadirla antes de hacer ningún imports.

Trust Flex Graphics Tablet

lunes, agosto 20th, 2018

El otro día me compré una tableta gráfica Trust Flex Graphics Tablet. No es que suela dibujar a menudo, pero de vez en cuando me gusta hacer alguna cosa, y según qué tareas me dejan la muñeca fatal si las hago con el ratón.

Por desgracia ya al principio empezaron los problemas, pues Linux no me la detectaba. Sin embargo, lo raro era que sí había un dispositivo en /dev/input de la tableta, simplemente no se reconocía como un dispositivo digitalizador.

Empecé a rebuscar y encontré, por fin, gracias a una entrada del gitlab de freedesktop, que el problema se debe a que la tableta no entrega la resolución en unidades físicas; esto es, no se puede saber directamente a cuantos milímetros se corresponde unas coordenadas de posición. La solución consiste en añadir estas líneas en el fichero /etc/udev/hwdb.d/60-evdev.hwdb (creándolo si no existe):

#########################################
# Trust
#########################################

# Trust Flex Graphics Tablet
evdev:input:b0003v2179p0004*
 EVDEV_ABS_00=::234
 EVDEV_ABS_01=::328

Estas líneas añaden la entrada EVDEV_ABS_XX a los datos devueltos por el driver, de manera que libinput puede saber la resolución física de la tableta.

Una vez hecho esto hay que compilar el fichero mediante el comando

sudo udevadm hwdb --update

Y finalmente reiniciar para que el sistema aplique los cambios (sí, es necesario). Una vez hecho esto, la tableta funcionará perfectamente, apareciendo en pantalla un segundo cursor que seguirá al bolígrafo.

dbForge Mysql en Wine

lunes, marzo 19th, 2018

Por una serie de circunstancias tengo que usar dbForge. Dado que se trata de un programa de windows parecía que no había otra que meter una máquina virtual, pero es un entorno que siempre supone un engorro porque no es directo conmutar desde ella hasta algún programa en el sistema operativo maestro. Ante esto decidí intentar hacerlo funcionar en Wine.

El primer problema que me encontré al intentar ejecutar el instalador fue que me exigía un entorno de 32 bits. Para no interferir con otros entornos de wine opté por crear uno independiente. Para ello, en la línea de comandos ejecuté:

export WINEPREFIX=~/.wine32
export WINEARCH=win32

Una vez hecho esto ya ejecutaba el instalador, pero me pedía .NET 3.5 SP1 o superior, y aquí empezaron los problemas. Probé a bajar el instalador de dicho .NET, pero no se dejaba instalar. Rebuscando, en varias páginas indicaban que había que usar winetricks para instalarlo. Así lo intenté con:

winetricks dotnet35sp1

Sin embargo, no se instalaba: algo fallaba en winetricks que la instalación fallaba.

Probé a instalar Mono para windows, pero no sirvió tampoco: el instalador no lo reconocía como un entorno .NET.

Tras varias pruebas infructuosas, finalmente se me ocurrió probar a instalar la versión 4.0 de .NET con:

winetricks dotnet40

Y esta vez sí se instaló completamente. Una vez instalado, probé el instalador de dbForge y también funcionó, así como el programa en sí (aunque da un pequeño aviso, indicando que necesita la versión 2.0 de .NET y que si se quiere bajar; basta con decir «No» y funcionará igualmente bien).

Cuando WiFi y Bluetooth chocan

viernes, febrero 16th, 2018

Hace unos días mi padre estaba sufriendo un problema bastante raro: la conexión a internet de su nuevo móvil iba realmente mal y no recibía mensajes, pero sólo cuando usaba la WiFi de casa. Hice algunas pruebas y, efectivamente, con la WiFi era imposible navegar desde el móvil o enviar mensajes: prácticamente no funcionaba. De vez en cuando enviaba algún que otro mensaje, o era capaz de cargar media página, pero enseguida fallaba de nuevo.

Empecé a hacer pruebas y, de casualidad, llegué hasta el Bluetooth: cuando estaba activo la WiFi no funcionaba, pero si lo desactivaba, funcionaba todo perfectamente. Por desgracia, dado que mi padre tiene un manos libres en el coche, desactivarlo siempre no era una opción, y andar conectándolo cada vez que se sube al coche no es una solución práctica, porque, como nos pasaría a todos, o se olvidaría de encenderlo al subir, o se olvidaría de apagarlo al bajar.

En parte tiene sentido que el Bluetooth interfiera con la WiFi, porque ambos trabajan en la misma banda de frecuencia: 2,4GHz. Sin embargo, lo raro es que no ocurriese con el móvil viejo, así que tocó seguir investigando. ¿Era un problema de ese modelo concreto, tal vez?

La solución apareció por sorpresa: el motivo es que el móvil viejo sólo tenía WiFi 802.11g (que da un máximo de 54 megas por segundo), mientras que el nuevo tiene WiFi 802.11n (que puede dar hasta 300Mbps). Parece que el WiFi n es mucho más sensible a las interferencias, y tener un emisor (el de Bluetooth) tan cerca de su antena hace que no sea capaz de transmitir o recibir de manera fiable.

La solución, al final, consistió en ir al router y configurarlo para que sólo aceptase conexiones WiFi 802.11b/g, en lugar del modo por defecto que era 802.11b/g/n. De esta manera nunca se intentará conectar mediante el protocolo más moderno, y todo funcionará correctamente. Es la mejor opción, además, porque mezclar dispositivos 802.11g con 802.11n hace que el rendimiento de ambos baje mucho, con lo que es mejor que todos se conecten con el mismo protocolo.

El problema lo tengo ahora con mi sobrino, porque le pasa algo parecido pero su router, de Vodafone, no deja al usuario normal cambiar los protocolos, sólo el administrador. A ver si desde el servicio técnico nos lo hacen. Si no, tocará capar todos los equipos de casa uno a uno para que sean ellos los que no se conecten en modo 802.11n.

VirtualBox y Windows 10

viernes, junio 2nd, 2017

Por circunstancias de la vida he tenido que usar Windows 10 en una máquina virtual sobre Linux, así que, por comodidad, decidí usar VirtualBox. Mi sorpresa fue descubrir lo terriblemente lento que iba. Por algún motivo se pasaba todo el rato accediendo al disco duro, y eso enlentecía el sistema hasta límites exasperantes.

Afortunadamente, rebuscando, encontré la solución:

  • Pulsar «Windows»+R, para ejecutar una aplicación, y lanzar «services.msc»
  • Buscar «Windows Search» y «Superfetch».
  • En cada uno, ir a Propiedades, detenerlo, y desactivarlo.
  • Profit!

Más Gentoo para MipsEL

domingo, diciembre 25th, 2016

Estoy actualizando la distribución de Gentoo para webtv y, como no podía ser de otra manera, hay problemillas. El último ha sido con busybox. Para poder compilarla hay que añadir, además de las opciones que indico en Generando Gentoo para WebTV, hay que añadir las siguientes:

busybox_config_option n NANDWRITE
busybox_config_option n NANDDUMP
busybox_config_option n FLASH_ERASEALL
busybox_config_option n FLASHCP
busybox_config_option n BLKDISCARD

Por otro lado, la variable USE debe contener:

USE="${ARCH} -pam -fortran -sanitize -X -iptables -hardened -seccomp -ipv6 -systemd -mdev internal-glib -caps -gtk -qt -t -boehm-gc -nls -filecaps"

Preparando Gentoo de nuevo

lunes, diciembre 19th, 2016

Estoy preparando una nueva versión de Transmission para el WebTV, y como perdí el sistema Gentoo que había construido hace tiempo he tenido que volver a generarlo, siguiendo mis propias notas.

Sin embargo esta vez me apareció un problema extra una vez finalizado todo. Para empezar, Python siguió dando problemas, así que compilé la versión 3.4 de manera cruzada y dejé para compilar en nativo la versión 3.5. Pero una vez compilado todo, y tras entrar con systemd-nspawn, me encuentro con que varios comandos, entre ellos el importantísimo emerge, devuelven un error rarísimo:

mipsel-unknown-linux-gnu / # env-update
Traceback (most recent call last):
  File "/usr/lib/python-exec/python3.4/env-update", line 31, in 
    import portage
ImportError: No module named 'portage'

Tras muchas pruebas, descubrí que el problema era que, como el sistema gentoo nativo era de 64 bits, metió muchas bibliotecas en /usr/lib64, directorio que el sistema Mipsel no encontraba porque es de 32 bits.

La solución fue tan sencilla como copiar recursivamente /usr/lib64 a /usr/lib.


Utilizamos cookies para garantizar que tenga la mejor experiencia en nuestro sitio web.