日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GNOME Shell Extensions开发介绍

發布時間:2024/1/17 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GNOME Shell Extensions开发介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前兩天看到這篇介紹gnome shell extensions 開發的文章,來自blog.fpmurphy.com 很不錯,特轉來留著。有興趣的人看看吧。

GNOME Shell Extensions

The new GNOME Shell in GNOME 3 includes support for GNOME Shell extensions. What, you may ask, is a GNOME Shell extension? According to the GNOME web page on GNOME Shell extensions

the GNOME Shell extension design is designed to give a high degree of power to the parts of the GNOME interface managed by the shell, such as window management and application launching. It simply loads arbitrary JavaScript and CSS. This gives developers a way to make many kinds of changes and share those changes with others, without having to patch the original source code and recompile it, and somehow distribute the patched code.

In other ways, a GNOME Shell extension can be used to alter the existing functionality of the GNOME Shell or to provide additional functionality.

This post assumes that you are familiar with the GNOME 3 Shell provided in Fedora 15 and have a working knowledge of JavaScript. By means of a number of examples, it will introduce you to some of the key concepts required to write you own extension. As with a lot of my posts, this post will be a living document and will be edited from time to time to correct errors and add more examples.

So how should you go about creating a GNOME Shell extension? Let us dive in an create a simple extension and explain the concepts and theory as we go along. We will use gnome-shell-extension-tool for our first example. This tool is available in Fedora 15 Alpha. I am not sure whether it is available on other GNU/Linux distributions. There is no manpage for this tool but it is simple to use. Just answer a couple of questions and all the necessary files are created for you.

$ gnome-shell-extension-tool --help
Usage: gnome-shell-extension-tool [options]
Options:
-h, --help show this help message and exit
--create-extension Create a new GNOME Shell extension

Example 1:

Suppose I use this gnome-shell-extension-tool to create an extension named helloworld with a UUID of helloworld@example.com and a description of My first GNOME 3 Shell extension. The tool, which is just a Python script, creates an appropriately named subdirectory (actually it is the uuid of the extension) under ~/.local/share/gnome-shell/extensions and populates that subdirectory with three files. Note that the UUID can be the classical 128 bit number, some other number or alphanumeric combination, or something more mundane like helloworld@example.com. So long as it can be used to create a subdirectory, it will be regarded as a valid UUID.

$ cd .local/share/gnome-shell/extensions
$ find ./
./helloworld@example.com
./helloworld@example.com/stylesheet.css
./helloworld@example.com/extension.js
./helloworld@example.com/metadata.json
$ cd helloworld@example.com
$ ls -l
-rw-rw-r--. 1 fpm fpm 718 Mar 31 00:24 extension.js
-rw-rw-r--. 1 fpm fpm 137 Mar 31 00:23 metadata.json
-rw-rw-r--. 1 fpm fpm 177 Mar 31 00:23 stylesheet.css


Here are the contents of these three files:

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 $ cat metadata.json { ???"shell-version": ["2.91.92"], ???"uuid": "helloworld@example.com", ???"name": "helloworld", ???"description": "My first GNOME 3 Shell extension" } $ cat extension.js // // Sample extension code, makes clicking on the panel show a message // const St = imports.gi.St; const Mainloop = imports.mainloop; const Main = imports.ui.main; function _showHello() { ????let text = new St.Label({ style_class: 'helloworld-label', text: "Hello, world!" }); ????let monitor = global.get_primary_monitor(); ????global.stage.add_actor(text); ????text.set_position(Math.floor (monitor.width / 2 - text.width / 2), ??????????????????????Math.floor(monitor.height / 2 - text.height / 2)); ????Mainloop.timeout_add(3000, function () { text.destroy(); }); } // Put your extension initialization code here function main() { ????Main.panel.actor.reactive = true; ????Main.panel.actor.connect('button-release-event', _showHello); } $ cat stylesheet.css /* Example stylesheet */ .helloworld-label { ????font-size: 36px; ????font-weight: bold; ????color: #ffffff; ????background-color: rgba(10,10,10,0.7); ????border-radius: 5px; }


What is created is a very simple extension that display a message, Hello, world!, in the middle of your screen as shown below whenever you click the panel (the horizontal bar at the top of your screen in the GNOME 3 Shell) or a menu selection.

This extension is created under ~/.local/share/gnome-shell/extensions which is the designated location for per user extensions. Note that ~/.local is also used for other purposes, not just for per user extensions.

$ find .local
.local
.local/share
.local/share/gnome-shell
.local/share/gnome-shell/extensions
.local/share/gnome-shell/extensions/helloworld@example.com
.local/share/gnome-shell/extensions/helloworld@example.com/stylesheet.css
.local/share/gnome-shell/extensions/helloworld@example.com/extension.js
.local/share/gnome-shell/extensions/helloworld@example.com/metadata.json
.local/share/gnome-shell/application_state .local/share/icc
.local/share/icc/edid-67c2e64687cb4fd59883902829614117.icc
.local/share/gsettings-data-convert


Global (system-wide) extensions should be placed in either /usr/share/gnome-shell/extensions or /usr/local/share/gnome-shell/extensions.

By the way I really wish the GNOME developers would stop creating more and more hidden subdirectories in a users home directory! It would be really nice if everything to do with GNOME 3 was located under, say, .gnome3.

Notice that the actual code for the extension is written in JavaScript and contained in a file called extension.js. This file is mandatory and is what gets loaded into GNOME Shell. At a minimum, it must contain a main() function which is invoked immediately after the extension is loaded by GNOME shell.

The JavaScript language version is 1.8 (which is a Mozilla extension to ECMAscript 262.) This is why non-standard JavaScript keywords like let are supported in shell extensions. The actual JavaScript engine (called gjs) is based on the Mozilla SpiderMonkey JavaScript engine and the GObject introspection framework.

Interestingly, a gjs shell is provided but unfortunately most of the shell functionality present in SpiderMonkey such as quit() does not appear to be supported in this particular JavaScript shell

$ gjs
** (gjs:11363): DEBUG: Command line: gjs
** (gjs:11363): DEBUG: Creating new context to eval console script
gjs> help() ReferenceError: help is not defined
gjs> quit() ReferenceError: quit is not defined
gjs>


Persistent metadata for the extension is stored in the file metadate.json which uses the JSON file format. JSON was chosen because it is natively supported by JavaScript. Here is the current list of defined strings:

  • shell-version: A list of GNOME Shell versions compatible with the extension. For example ["2.91.92", "3.0.0"].
  • uuid: A unique UUID for the extension. This must be unique among any installed extensions as the UUID is used as the name of the subdirectory under which the files for the extension are located.
  • name: The name of the extension. This is displayed by the Looking Glass debugger when the extensions panel is displayed.
  • description: The description of the extension. This is also displayed by Looking Glass when the extensions panle is displayed.
  • url: [OPTIONAL] A valid URL pointing the the source code for the extension. Looking Glass uses this URL, if provided, to display a button which when pressed opens the source code file.
  • js-version: [OPTIONAL] This can be used to specify that a particular version of hjs is required by the extension.

There is nothing stopping you adding additional strings to this file. It some cases this may be useful as the contents of metadata.json is passed as an argument to the main() function in extension.js.

The third file is stylesheet.css. This contains all the CSS (Cascading Style Sheet) information for your extension. This file is not required if your particular extension does not require it’s own presentation markup.

Example 2:

What if we want to display localized message strings (always a good idea!) in our helloworld shell extension. In this case we need to modify entension.js to support message catalogs and we need to provide and install the relevant message catalogs in the appropriate directories.

The GNOME Shell uses the standard GNU/Linux gettext paradigm. I am going to assume that you are somewhat familiar with software localization and how to use gettext. A whole post could be devoted to the use of gettext but that is not the purpose of this post.

Fortunately the heavy lifting has been done for us by others and a JavaScript binding to gettext is available to us. We import the necessary JavaScript gettext module into the helloworld shell extension using imports and modify the code to use Gettext.gettext(“message string”) to retrieve the localized version of the message string if provided in a message catalog.

Normally compiled gettext message catalogs (.mo files) are placed under /usr/share/locale on GNU/Linux distributions. However I do not think that this is a good location for extension message catalogs as I believe that extensions should be as self-contained as possible to aid in their easy installation and removal. It also avoids the possibility of message catalog namespace collisions. For this reason, we place the message catalogs in a subdirectory called locale under the top directory of the extension.

By way of example, here is a listing of the files for our helloworld extension after it has been modified to support message localization and message catalogs for en_US and fr_FR locales provided.

./helloworld@example.com
./helloworld@example.com/stylesheet.css
./helloworld@example.com/extension.js
./helloworld@example.com/locale
./helloworld@example.com/locale/fr_FR
./helloworld@example.com/locale/fr_FR/LC_MESSAGES
./helloworld@example.com/locale/fr_FR/LC_MESSAGES/helloworld.mo
./helloworld@example.com/locale/fr_FR/LC_MESSAGES/helloworld.po
./helloworld@example.com/locale/en_US ./helloworld@example.com/locale/en_US/LC_MESSAGES
./helloworld@example.com/locale/en_US/LC_MESSAGES/helloworld.mo
./helloworld@example.com/locale/en_US/LC_MESSAGES/helloworld.po
./helloworld@example.com/metadata.json


As you can see I have provided support for two locales, en_US for Americanese speakers and fr_FR for French speakers. The default message string Hello, world! will be displayed if neither of these two locales is set. Only the .mo files are necessary but I suggest that the corresponding .po files also reside there to make it easy to update a message catalog.

Here is our entension.js after it was modified to support message string localization:

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const St = imports.gi.St; const Mainloop = imports.mainloop; const Main = imports.ui.main; const Gettext = imports.gettext; function _showHello() { ????let text = new St.Label({ style_class: 'helloworld-label', ??????????????????????????????text: Gettext.gettext("Hello, world!") }); ????let monitor = global.get_primary_monitor(); ????global.stage.add_actor(text); ????text.set_position(Math.floor (monitor.width / 2 - text.width / 2), ??????????????????????Math.floor(monitor.height / 2 - text.height / 2)); ????Mainloop.timeout_add(3000, function () { text.destroy(); }); } function main(extensionMeta) { ????let userExtensionLocalePath = extensionMeta.path + '/locale'; ????Gettext.bindtextdomain("helloworld", userExtensionLocalePath); ????Gettext.textdomain("helloworld"); ????Main.panel.actor.reactive = true; ????Main.panel.actor.connect('button-release-event', _showHello); }


Note that the main function now has one parameter extensionMeta. This is an object that contains all the information from the extension’s metadata.json file. This is the only parameter available to the main function in an extension. See the loadExtension function in /usr/share/gnome-shell/js/ui/extensionSystem.js for further details.

This parameter is used to build the path to the shell extension locale subdirectory. We then tell gettext that we want to use message catalogs from this subdirectory using bindtextdomain and specify the relevant message catalog, helloworld.mo, using textdomain.

Here is what is displayed when the locale is set to en_US:

and here is what is displayed when the locale set to fr_FR

If no suitable message catalog is found, the message string Hello, world! will be displayed.

Example 3:

This example shows you how modify our helloworld example extension to add a menu item to the Status Menu (the menu at the top right hand corner) of your primary display and output the Hello, world! message.

Here is the modified extensions.js:

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 const Main = imports.ui.main; const Shell = imports.gi.Shell; const Lang = imports.lang; const PopupMenu = imports.ui.popupMenu; const Gettext = imports.gettext; const _ = Gettext.gettext; function _showHello() { ????let text = new St.Label({ style_class: 'helloworld-label', text: _("Hello, world!") }); ????let monitor = global.get_primary_monitor(); ????global.stage.add_actor(text); ????text.set_position(Math.floor (monitor.width / 2 - text.width / 2), ??????????????????????Math.floor(monitor.height / 2 - text.height / 2)); ????Mainloop.timeout_add(3000, function () { text.destroy(); }); } function main(extensionMeta) { ????let userExtensionLocalePath = extensionMeta.path + '/locale'; ????Gettext.bindtextdomain("helloworld", userExtensionLocalePath); ????Gettext.textdomain("helloworld"); ????let statusMenu = Main.panel._statusmenu; ????// use this in future:? let statusMenu = Main.panel._userMenu; ????let item = new PopupMenu.PopupSeparatorMenuItem(); ????statusMenu.menu.addMenuItem(item); ????item = new PopupMenu.PopupMenuItem(_("Hello")); ????item.connect('activate', Lang.bind(this, this._showHello)); ????statusMenu.menu.addMenuItem(item); }


Note the use of const _ to make message strings note legible in the source code.

Notice how we increased the size of the message box. No code changes were required; we simply edited the relevant styling markup. Here is the new version of stylesheet.css

1 2 3 4 5 6 7 8 .helloworld-label { ????font-size: 36px; ????font-weight: bold; ????color: #ffffff; ????background-color: rgba(10,10,10,0.7); ????border-radius: 15px; ????margin: 50px; ????padding: 50px;

Example 4:

This example modifies the previous example to display a message in the GNOME Shell message tray.

Here is the modified extensions.js:

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 const St = imports.gi.St; const Mainloop = imports.mainloop; const Main = imports.ui.main; const Shell = imports.gi.Shell; const Lang = imports.lang; const PopupMenu = imports.ui.popupMenu; const Gettext = imports.gettext; const MessageTray = imports.ui.messageTray; const _ = Gettext.gettext; function _myNotify(text) { ????global.log("_myNotify called: " + text); ????let source = new MessageTray.SystemNotificationSource(); ????Main.messageTray.add(source); ????let notification = new MessageTray.Notification(source, text, null); ????notification.setTransient(true); ????source.notify(notification); } function _showHello() { ???_myNotify(_("Hello, world!")) ????let text = new St.Label({ style_class: 'helloworld-label', text: _("Hello, world!") }); ????let monitor = global.get_primary_monitor(); ????global.stage.add_actor(text); ????text.set_position(Math.floor (monitor.width / 2 - text.width / 2), ??????????????????????Math.floor(monitor.height / 2 - text.height / 2)); ????Mainloop.timeout_add(3000, function () { text.destroy(); }); } function main(extensionMeta) { ????let userExtensionLocalePath = extensionMeta.path + '/locale'; ????Gettext.bindtextdomain("helloworld", userExtensionLocalePath); ????Gettext.textdomain("helloworld"); ????let statusMenu = Main.panel._statusmenu; ????let item = new PopupMenu.PopupSeparatorMenuItem(); ????statusMenu.menu.addMenuItem(item); ????item = new PopupMenu.PopupMenuItem(_("Hello, world!")); ????item.connect('activate', Lang.bind(this, this._showHello)); ????statusMenu.menu.addMenuItem(item); }


Note the use of global.log to log a message to the error log. This log can be viewed in Looking Glass. This is useful when debugging an extension.

Example 5:

This example demonstrates how to modify our helloworld extension to add a button to the panel which when pressed displays a single option menu which when selected displays our Hello, world! message.

Here is the modified extensions.js:

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 const St = imports.gi.St; const Mainloop = imports.mainloop; const Main = imports.ui.main; const Shell = imports.gi.Shell; const Lang = imports.lang; const PopupMenu = imports.ui.popupMenu; const PanelMenu = imports.ui.panelMenu; const Gettext = imports.gettext; const MessageTray = imports.ui.messageTray; const _ = Gettext.gettext; function _myButton() { ????this._init(); } _myButton.prototype = { ????__proto__: PanelMenu.Button.prototype, ????_init: function() { ????????PanelMenu.Button.prototype._init.call(this, 0.0); ????????this._label = new St.Label({ style_class: 'panel-label', text: _("HelloWorld Button") }); ????????this.actor.set_child(this._label); ????????Main.panel._centerBox.add(this.actor, { y_fill: true }); ????????this._myMenu = new PopupMenu.PopupMenuItem(_('HelloWorld MenuItem')); ????????this.menu.addMenuItem(this._myMenu); ????????this._myMenu.connect('activate', Lang.bind(this, _showHello)); ????}, ????_onDestroy: function() {} }; function _showHello() { ????let text = new St.Label({ style_class: 'helloworld-label', text: _("Hello, world!") }); ????let monitor = global.get_primary_monitor(); ????global.stage.add_actor(text); ????text.set_position(Math.floor (monitor.width / 2 - text.width / 2), ??????????????????????Math.floor(monitor.height / 2 - text.height / 2)); ????Mainloop.timeout_add(3000, function () { text.destroy(); }); } function main(extensionMeta) { ????let userExtensionLocalePath = extensionMeta.path + '/locale'; ????Gettext.bindtextdomain("helloworld", userExtensionLocalePath); ????Gettext.textdomain("helloworld"); ????let _myPanelButton = new _myButton(); }


Here is the modified stylesheet.css

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 .panel-label { ????padding: .4em 1.75em; ????font-size: 10.5pt; ????color: #cccccc; ????font-weight: bold; } .helloworld-label { ????font-size: 36px; ????font-weight: bold; ????color: #ffffff; ????background-color: rgba(10,10,10,0.7); ????border-radius: 15px; ????margin: 50px; ????padding: 50px;

Example 6:

This example demonstrates how to modify our helloworld extension to change the hotspot button to display the Fedora logo in the upper left corner instead of the string Activities.

Here is the modified extensions.js. As you can see it contains only a few lines of JavaScript.

01 02 03 04 05 06 07 08 09 10 11 12 13 const St = imports.gi.St; const Main = imports.ui.main; function main() { ???hotCornerButton = Main.panel.button; ???let logo = new St.Icon({ icon_type: St.IconType.FULLCOLOR, icon_size: hotCornerButton.height, icon_name: 'fedora-logo-icon' }); ???let box = new St.BoxLayout(); ???box.add_actor(logo); ???Main.panel.button.set_child(box); }


No stylesheet.css is required as this particular extension is not using any presentation markup.

Example 7:

This example demonstrates how to remove the Computer Accessibility (AKA a11y icon and menu from the status tray in the panel.

Consider the following extensions.js. As you can see it contains only a few lines of JavaScript.

1 2 3 4 5 6 const Panel = imports.ui.panel; function main() { ???Panel.STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['a11y'] = ''; }


No stylesheet.css is required since the extension uses no presentation markup. This solution works. You no longer see the a11y status icon. However a SystemStatusButton object (see panelMenu.js ) is left dangling. A better approach is to do something like the following:

01 02 03 04 05 06 07 08 09 10 const Panel = imports.ui.panel; function main() { ????let index = Panel.STANDARD_TRAY_ICON_ORDER.indexOf('a11y'); ????if (index >= 0) { ????????Panel.STANDARD_TRAY_ICON_ORDER.splice(index, 1); ????} ????delete Panel.STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['a11y']; }


This extension is available as noa11y-1.0.tar.gz in the extensions area of my website.

Turning now to the question of how to determine which GNOME Shell extensions are loaded and what information is available about the state of such extensions. Currently no tool is provided in a distribution to list information about extensions.

Here is a small Python utility which lists the details of all your GNOME Shell extensions on the command line:

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 #!/usr/bin/python # # Copyright (c) 2011 Finnbarr P. Murphy # # This utility is free software. You can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 2 of # the License, or (at your option) any later version. # # This utility is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.? See the # GNU General Public License for more details. # # See for full text of the license. # import os.path import json from gi.repository import Gio from gi.repository import GLib state = { 1:"enabled", 2:"disabled", 3:"error", 4:"out of date"} type? = { 1:"system", 2:"per user"} class GnomeShell: ????def __init__(self): ????????d = Gio.bus_get_sync(Gio.BusType.SESSION, None) ????????self._proxy = Gio.DBusProxy.new_sync( ????????????????????????????d, 0, None, ????????????????????????????'org.gnome.Shell', ????????????????????????????'/org/gnome/Shell', ????????????????????????????'org.gnome.Shell', ????????????????????????????None) ????def execute_javascript(self, js): ????????result, output = self._proxy.Eval('(s)', js) ????????if not result: ????????????raise Exception(output) ????????return output ????def list_extensions(self): ????????out = self.execute_javascript('const ExtensionSystem = imports.ui.extensionSystem; ExtensionSystem.extensionMeta') ????????return json.loads(out) ????def get_shell_version(self): ????????out = self.execute_javascript('const Config = imports.misc.config; version = Config.PACKAGE_VERSION') ????????return out ????def get_gjs_version(self): ????????out = self.execute_javascript('const Config = imports.misc.config; version = Config.GJS_VERSION') ????????return out if __name__ == "__main__": ????s = GnomeShell() ????print ????print "Shell Version:", s.get_shell_version() ????print "? GJS Version:",? s.get_gjs_version() ????print ????l = s.list_extensions() ????for k, v in l.iteritems(): ????????print 'Extension: %s' % k ????????print "-" * (len(k) + 11) ????????for k1, v1 in v.iteritems(): ????????????if k1 == 'state': ????????????????print '%15s: %s (%s)' % (k1, v1, state[v1]) ????????????elif k1 == 'type': ????????????????print '%15s: %s (%s)' % (k1, v1, type[v1]) ????????????elif k1 == 'shell-version': ????????????????print '%15s:' % k1, ????????????????print ", ".join(v1) ????????????else: ????????????????print '%15s: %s' % (k1, v1) ????????print


Here is what is outputted for our HelloWorld example extension:

Shell Version: "3.0.0"
GJS Version: "0.7.13"

Extension: helloworld@example.com
---------------------------------
description: My first GNOME 3 Shell extension
shell-version: 2.91.91, 2.91.92, 2.91.93
       name: helloworld
        url: http://example.com
      state: 1 (enabled)
       path: /home/fpm/.local/share/gnome-shell/extensions/helloworld@example.com
       type: 2 (per user)
       uuid: helloworld@example.com


You can also see which extensions are loaded using the Looking Glass debugger which is accessible via Alt-F2 lg. Unfortunately, the current version of Looking Glass displays very little information about extensions other than the fact that they are loaded, but that is easily remedied by adding a few lines of JavaScript to /usr/share/gnome-shell/js/ui/lookingGlass.js.

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 $ diff lookingGlass.js.org lookingGlass.js 621a622,631 >???? _typeToString: function(extensionType) { >???????? switch (extensionType) { >???????????? case ExtensionSystem.ExtensionType.SYSTEM: >???????????????? return _("System"); >???????????? case ExtensionSystem.ExtensionType.PER_USER: >???????????????? return _("Per User"); >???????? } >???????? return 'Unknown'; >???? }, > 637a648 >???????? let line1Box = new St.BoxLayout(); 640d650 <???????? box.add(name, { expand: true }); 642,643c652,655 <????????????????????????????????????????? text: meta.description }); <???????? box.add(description, { expand: true }); --- >????????????????????????????????????????? text: "? " + meta.description }); >???????? line1Box.add(name, { expand: false }); >???????? line1Box.add(description, { expand: false }); >???????? box.add(line1Box); 645,647d656 <???????? let metaBox = new St.BoxLayout(); <???????? box.add(metaBox); <???????? let stateString = this._stateToString(meta.state); 649c658,667 <??????????????????????????????????? text: this._stateToString(meta.state) }); --- >??????????????????????????????????? text: "? State: " + this._stateToString(meta.state)+", " }); >???????? let type = new St.Label({ style_class: 'lg-extension-state', >??????????????????????????????????? text: "Type: " + this._typeToString(meta.type)+", " }); >???????? let uuid = new St.Label({ style_class: 'lg-extension-state', >??????????????????????????????????? text: "UUID: " + meta.uuid }); > >???????? let metaDataBox = new St.BoxLayout(); >???????? metaDataBox.add(state, { expand: false }); >???????? metaDataBox.add(type, { expand: false }); >???????? metaDataBox.add(uuid, { expand: false }); 650a669,670 >???????? let metaBox = new St.BoxLayout(); >???????? box.add(metaBox); 666a687,690 >???????? actionsBox.add(metaDataBox);


Here is what is displayed by the modified Looking Glass for our HelloWorld extension:

How do you disable or enable installed extensions? By default, all extensions are enabled provided they match the current GNOME Shell version number (and the gjs version number if one is provided in metadata.json.) You can disable extensions from the command line using the gsettings utility. You should also be able to disable extensions using dconf-editor but this utility is broken as of the date of this post (and seems to be always broken for some reason or other) so I cannot test it. At present there is no specific GUI-based utility to disable or enable extensions.

$ gsettings list-recursively
org.gnome.shell org.gnome.shell command-history @as []
org.gnome.shell development-tools true
org.gnome.shell disabled-extensions @as []
org.gnome.shell disabled-open-search-providers @as []
org.gnome.shell enable-app-monitoring true
org.gnome.shell favorite-apps ['mozilla-firefox.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'openoffice.org-writer.desktop', 'nautilus.desktop']
org.gnome.shell looking-glass-history @as []
org.gnome.shell.calendar show-weekdate false
org.gnome.shell.clock show-date false
org.gnome.shell.clock show-seconds false
org.gnome.shell.recorder file-extension 'webm'
org.gnome.shell.recorder framerate 15
org.gnome.shell.recorder pipeline ''
[root@ultra noarch]#


The requisite key is disabled-extensions

$ gsettings get org.gnome.shell disabled-extensions
@as []


The @as [] syntax is outputted whenever there are no disabled GNOME Shell extensions. This indicates a serialized GVariant. A GVariant is a variant datatype; it stores a value along with the type of that value.

To disable an extension, simply add the UUID of the extension to the disabled-extensions key, logout and log back in, or reload the GNOME Shell using Alt-F2 r. Note that disabling an extension does not stop it operating once it has been loaded into the GNOME Shell; it merely stops it being loaded in the first place.

$ gsettings set org.gnome.shell disabled-extensions "['helloworld@example.com']"


By the way, gsettings does not handle incrementally adding an extensions’ UUID to the disabled-extensions key nor does it overwrite or remove existing values. You first have to reset the key and then set the key with the new values.

$ gsettngs reset org.gnome.shell disabled-extensions
$ gsettings set org.gnome.shell disabled-extensions "['helloworld@gnome.org']"

Recently an official repository for GNOME Shell extensions was created by Giovanni Campagna. As of the date of this post it includes the following extensions:

  • alternate-tab: provides the classic GNOME Alt+Tab functionality.
  • alternative-status-menu: replaces the status menu with one featuring separate Suspend and Power Off menu options.
  • auto-move-windows: assigns a specific workspace to each application as soon as it creates a window, in a configurable manner.
  • dock: displays a docked task switcher on the right side of your screen.
  • example: a minimal example illustrating how to write extensions.
  • gajim: provides integration with Gajim, a Jabber/XMPP instant messaging client.
  • user-theme: loads a user specified shell theme.
  • windowsNavigator: enables keyboard selection of windows and workspaces in overlay mode.
  • xrandr-indicator: enable you to rotate your screen and access display preferences quickly.

Currently these extensions are not available as RPMs but I am sure that it will not take long before somebody does the necessary work to make this happen. If you want to build you own RPMs, here is a .spec file which packages the example shell extension. It assumes that the source files exist in gnome-shell-extensions.tar.gz in the build source directory. You can easily modify the file to use git archive –format=tar to pull the files directly from the extensions git repository and to build a package for other extensions.

Name: gnome-shell-extensions
Version: 2.91.6 Release: 1
License: GPLv2+
Group: User Interface/Desktops
Summary: A collection of extensions for the GNOME 3 Shell
Url: http://live.gnome.org/GnomeShell/Extensions
Source: %{name}.tar.gz
BuildRequires: gnome-common
BuildRequires: pkgconfig(gnome-desktop-3.0)
Requires: gnome-shell
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch

%description
GNOME Shell Extensions is a collection of extensions providing
additional optional functionality for the GNOME 3 Shell.

%prep
%setup -q -n %{name}
%build
# Needed because we build from a git checkout
[ -x autogen.sh ] && NOCONFIGURE=1 ./autogen.sh
%configure --enable-extensions="example" --prefix=$HOME/.local

%configure
make %{?_smp_mflags}
%install rm -rf $RPM_BUILD_ROOT
%make_install
%find_lang %{name}

%clean
%{?buildroot:%__rm -rf %{buildroot}}

%post

%postun
%files -f %{name}.lang
%defattr(-,root,root)
%doc README
%dir %{_datadir}/gnome-shell
%{_datadir}/gnome-shell/extensions/
%{_datadir}/glib-2.0/schemas/

%changelog
*Tue Mar 29 2011 1
-- Initial Build


I am going to assume that you know how to build RPMs. Since the GNOME Shell and, by extension (bad pun?), extensions are still a moving target at present, you will probably have to make minor changes to the above .spec file to meet your specific requirements and to conform to changes in the extensions repository. A word of caution however – if you build and install all the shell extensions that are in the repository at the one time, you will most certainly break GNOME Shell.

What are my thoughts on an architecture and framework for extensions? Based on my experience with developing extensions for Mozilla Firefox, WordPress and suchlike, I believe that:

  • Each extension should be packaged separately to allow for individual installation, updating or removal.
  • Extensions do not need to be packaged as RPMs but should be compressed into some kind of tarball or zip file. An extension installation tool i(possibly part of the GNOME Shell, should unpack the extension tarball, do some sanity checking, and then install the extension.
  • All files, including message catalogs, images, and icons, for an extension should live under the extension top directory.
  • There needs to be a GUI for listing, installing, disabling, enabling and removing extensions.
  • There needs to be a better version checking mechanism in extensionSystem.js. The current code is too restrictive and does not support range checking, i.e. minimum and maximum supported versions.
  • GNOME Shell needs to guarantee some set of public hooks (APIs) that extensions can depend upon.
  • There needs to be a basic validation/testsuite for extensions.
  • An ecosystem needs to be put in place around extensions. Something like addons.mozilla.org.
  • Whether an extension accepted or not should not depend on the whims of a single gatekeeper but solely depend on whether the extension met certain published guidelines.
  • Extensions should be disabled by default on installation to ensure stability of the Shell and require specific user action (white-list?) to enable.
  • There should be some mechanism in place to enable the order of loading of extensions to be specified.

The GNOME Shell is still under active development. It will probably be GNOME 3.2 before it stabilizes to the extent that serious effort will be expended developing an extensions ecosystem. A lot more documentation, tools and infrastructure need to be place before a formal reliable ecosystem for GNOME Shell extensions emerges.

As always, experiment and enjoy the experience!

P.S. If you have found this post via an Internet search, you might be interested to know that I have written a number of other posts in this blog about configuring and extending the GNOME 3 Shell. Most of the extensions that I have written are available here.






發音: 無拼音

所有意思

1.

轉載于:https://www.cnblogs.com/pmirhs0/archive/2011/10/27/2227138.html

總結

以上是生活随笔為你收集整理的GNOME Shell Extensions开发介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

不卡av电影在线 | 久久久精品国产一区二区 | 在线免费观看视频 | 成人午夜网 | 福利二区视频 | 欧美激情精品久久久久久免费印度 | 91免费看片黄 | 久久久久久久久久久久久久电影 | 国产黄大片在线观看 | 精品久久久久久亚洲综合网 | 免费在线观看av的网站 | 蜜臀久久99精品久久久无需会员 | 99精品在这里 | 国产剧情一区 | 国产麻豆视频免费观看 | 九九在线精品视频 | 国产糖心vlog在线观看 | 91精品国产一区二区三区 | 99爱精品视频 | 免费视频a| 国产五月| 免费91麻豆精品国产自产在线观看 | 麻豆传媒视频在线 | 欧美成人黄色片 | 国产原厂视频在线观看 | 色综合天天狠天天透天天伊人 | 一区二区三区免费在线播放 | 精品国产美女 | 九九亚洲精品 | av天天色| 亚洲欧美在线视频免费 | 99精品福利 | 国产午夜在线 | 91片黄在线观看动漫 | 久久99精品一区二区三区三区 | 国产高清绿奴videos | 国产成人在线一区 | 江苏妇搡bbbb搡bbbb | 免费在线a | 激情五月婷婷丁香 | 欧美日韩大片在线观看 | 在线色亚洲| 中文字幕在线一区二区三区 | 欧美日韩另类在线 | 成人黄色电影免费观看 | 亚洲一区美女视频在线观看免费 | 91av福利视频 | 日韩成人免费观看 | 国产 视频 久久 | 91精品在线免费观看 | 亚洲理论片在线观看 | 在线观看韩日电影免费 | 狠狠躁夜夜a产精品视频 | 日韩免费一区二区三区 | 国产成人精品999在线观看 | 三级av在线免费观看 | av大片网站 | 91精品亚洲影视在线观看 | 天天综合天天做天天综合 | 天天操,夜夜操 | 免费看污片 | 三级在线视频观看 | 中文字幕xxxx | 超碰97人人干 | 久久久久国产精品厨房 | 波多野结衣亚洲一区二区 | 欧美二区三区91 | 黄色视屏在线免费观看 | 国产精品不卡视频 | 国产午夜三级一区二区三 | 午夜国产在线 | 色婷婷中文 | 色综合天天天天做夜夜夜夜做 | 久草在线视频网站 | 国产精品成人免费 | 黄色午夜网站 | 亚洲精品一区二区精华 | 亚洲综合色激情五月 | 中文在线中文资源 | 天天操天天爱天天干 | 在线中文日韩 | av先锋影音少妇 | 色婷婷www| 一区二区三区韩国免费中文网站 | 亚洲精品成人av在线 | 美女视频又黄又免费 | 97狠狠操| 免费美女久久99 | 91精品国产福利在线观看 | 亚洲黄污| 一级片免费观看视频 | 国产剧情一区在线 | 麻豆小视频在线观看 | 三级黄色网址 | 国产精彩视频一区二区 | 国产精品一区二区久久 | 色资源二区在线视频 | 久久久久久久久免费 | 色婷婷88av视频一二三区 | www.精选视频.com | 丰满少妇高潮在线观看 | 久久热亚洲| 在线精品视频免费观看 | 日韩欧美高清一区二区 | 国产五月天婷婷 | 欧美日韩高清在线一区 | 综合色中色 | 久久视频国产 | 五月激情站 | 成人免费电影 | 欧美精品国产综合久久 | 日韩精品免费一线在线观看 | 免费视频久久久久 | 日韩电影久久久 | 亚洲一区精品人人爽人人躁 | 国产一区二区三区网站 | 日韩大片免费在线观看 | 久久综合久久综合这里只有精品 | 国产精品 久久 | 免费日韩一区二区 | 成人在线一区二区三区 | 久草免费在线观看 | 亚洲年轻女教师毛茸茸 | 日韩av一区二区三区四区 | 久久久久久久久黄色 | 国产日韩精品视频 | 国产裸体永久免费视频网站 | 2023亚洲精品国偷拍自产在线 | 8090yy亚洲精品久久 | 在线观看免费版高清版 | 免费黄色看片 | 日韩理论片在线观看 | 玖草影院| 福利片视频区 | 91麻豆精品 | 日日摸日日添夜夜爽97 | 91人人爽久久涩噜噜噜 | 久久黄色片子 | 毛片1000部免费看 | 成人免费在线视频 | av电影免费在线看 | 国产免费成人 | 日韩精品视频免费专区在线播放 | 中文字幕在线观看不卡 | 日韩黄色一级电影 | 免费观看十分钟 | 69精品视频 | 91精品导航 | 色综合久久久久综合99 | 久久精品99国产精品亚洲最刺激 | 国产特级毛片 | 欧美日韩精品在线 | www黄色com| 亚洲国产精品小视频 | 激情综合五月天 | 色悠悠久久综合 | 久久99这里只有精品 | 婷婷深爱网 | 51久久夜色精品国产麻豆 | 欧美成亚洲 | 亚洲精品理论片 | 久久国产品 | 人人澡人人爽 | 天天摸天天操天天舔 | 欧美在线1区| 日韩黄色在线 | 欧美日韩高清一区二区 | 91入口在线观看 | 国产精品视频区 | 天天干,天天插 | 一区二区三区在线视频111 | 伊人色综合久久天天网 | 麻豆传媒在线免费看 | 91香蕉国产 | 狠狠干夜夜爱 | 伊人小视频 | 欧美aⅴ在线观看 | av在线官网 | 黄色美女免费网站 | av高清一区二区三区 | 日韩视频一 | 蜜臀av性久久久久av蜜臀妖精 | 亚洲国产成人在线播放 | 欧美一级特黄aaaaaa大片在线观看 | 视频在线一区二区三区 | 伊人久久婷婷 | 手机在线欧美 | 99免费国产 | 青青河边草免费 | 色九九在线| 激情网站免费观看 | 奇米网8888 | 精品1区二区 | 久久高清国产视频 | 国产亚洲精品xxoo | 91精品在线免费观看视频 | 精品国产精品一区二区夜夜嗨 | 人成午夜视频 | 久久久久在线 | 免费观看成人av | 欧美日韩国产网站 | 黄av免费 | 中文一二区 | 国产精品第十页 | 色六月婷婷| 久久电影中文字幕视频 | 又色又爽又激情的59视频 | 99视频网站 | 久久精品亚洲精品国产欧美 | 天堂av在线7 | 日韩av男人的天堂 | 亚洲欧美激情插 | 中文字幕av免费在线观看 | 欧美色伊人 | 国产第一页福利影院 | 欧美日韩国产在线一区 | 久久久亚洲国产精品麻豆综合天堂 | 久久怡红院 | 欧美日韩精品国产 | 99视频在线 | 久久综合中文色婷婷 | 色偷偷男人的天堂av | 久久99网| 久久99精品国产麻豆宅宅 | 国产黄色理论片 | 高清一区二区三区 | 91久久一区二区 | 中文字幕在线视频国产 | 在线黄色av电影 | 国产精品第52页 | 六月丁香在线视频 | 国产高清在线一区 | 国产精品一区二区三区电影 | 狠狠色丁香 | 国产原创在线 | 91九色精品女同系列 | 成人在线播放免费观看 | 91原创在线观看 | 美女很黄免费网站 | 国产精品免费观看久久 | 亚洲粉嫩av| 伊人天天狠天天添日日拍 | 亚洲九九精品 | 九九热在线观看 | 亚洲成av人片在线观看香蕉 | 91九色蝌蚪视频在线 | 日韩av有码在线 | 中文字幕在线播放第一页 | 中文字幕免费高 | 国产高清av| 玖玖视频免费在线 | 麻豆视频免费版 | 日韩在线 | 国产精品久久久久影视 | 激情小说网站亚洲综合网 | 就色干综合 | 国产精品 中文字幕 亚洲 欧美 | 91在线视频观看免费 | 91香蕉国产 | 香蕉视频免费在线播放 | 91av视频在线免费观看 | 四虎影院在线观看av | 亚洲一区 影院 | 欧美色图视频一区 | 色网址99| 欧美一级在线观看视频 | 麻豆视频网址 | 91成人在线观看喷潮 | 92精品国产成人观看免费 | 99精品视频在线观看播放 | 日韩成人免费观看 | 在线视频精品播放 | 亚洲精品视频免费 | 奇人奇案qvod| 欧美a√大片 | 亚洲精品高清一区二区三区四区 | 一区 二区电影免费在线观看 | 9在线观看免费高清完整版在线观看明 | 中文一区在线观看 | 色在线视频网 | 小草av在线播放 | 久久久亚洲麻豆日韩精品一区三区 | 天天搞天天干天天色 | 亚洲v精品 | 亚洲一区av | 欧美日本日韩aⅴ在线视频 插插插色综合 | 麻豆免费精品视频 | 麻豆视频一区二区 | 五月亚洲综合 | 久草亚洲视频 | 亚洲黄色小说网 | 国产一区二区成人 | 欧美精品一区二区免费 | 亚洲精品国久久99热 | 中文字幕视频一区 | av高清一区| 国产视频1区2区 | 国产系列 在线观看 | 亚洲永久精品一区 | 日韩av在线小说 | 九九综合九九综合 | 蜜桃视频在线观看一区 | 成人午夜免费剧场 | 亚洲五月综合 | 日本3级在线观看 | 亚洲精品视频在 | 97超碰资源| 免费看网站在线 | 久久久综合 | 亚洲成av人影院 | 日日干av | 午夜免费视频网站 | 日韩网站在线看片你懂的 | 久久精品中文视频 | 亚洲黄色网络 | 美女免费黄网站 | 91精品毛片| 91精品在线免费 | 免费观看一级一片 | 51久久成人国产精品麻豆 | 日韩欧美在线观看 | 国产精国产精品 | 99热官网 | 国产一区二区精品久久91 | 天天操综合 | 日本在线h | 色www精品视频在线观看 | 国产一区自拍视频 | 亚洲三级黄色 | 久久久精品电影 | 视频一区二区免费 | 91高清完整版在线观看 | 久草在线视频精品 | 99精品在线 | 精品福利片 | 日韩精品在线一区 | www.五月婷婷.com | 亚洲精品国产视频 | 又紧又大又爽精品一区二区 | 久久全国免费视频 | 99精品国产福利在线观看免费 | 免费在线激情电影 | 亚洲最新av | 91九色国产视频 | 国产亚洲精品久久久久久久久久久久 | 国产午夜在线观看视频 | 色中色资源站 | 国产精品麻豆视频 | 久久超 | 亚洲精品免费观看视频 | 中文字幕国产一区 | 久久久久国产精品一区二区 | 黄色精品国产 | 又黄又色又爽 | 国产尤物在线 | 92av视频 | 在线成人中文字幕 | 日韩av看片 | 黄色精品网站 | 欧美一级片在线播放 | 中文字幕制服丝袜av久久 | 久久久国产精品电影 | 国产精品高清在线 | 一区二区三区四区免费视频 | 一区二区久久 | 丁香久久婷婷 | 美女av在线免费 | 国产白浆在线观看 | 亚洲高清av | 国产亚洲精品日韩在线tv黄 | 日韩超碰| 免费av网站观看 | 日韩电影一区二区三区在线观看 | 久久综合影音 | 亚洲免费在线播放视频 | 天天天天爱天天躁 | 中文字幕一区二区三区四区视频 | 在线精品观看 | 91高清一区| 一区二区三区精品在线视频 | 日韩va欧美va亚洲va久久 | 色婷婷av一区 | 99在线热播| 免费成人短视频 | 久久无码精品一区二区三区 | 日韩电影一区二区三区在线观看 | 97av在线视频| 天天干天天天天 | 国产 日韩 中文字幕 | 91精彩视频在线观看 | 免费在线观看午夜视频 | 久青草视频 | 一区二区三区国产欧美 | 91久草视频 | 久久www免费人成看片高清 | 欧美精品中文在线免费观看 | 99久久久国产精品免费观看 | 久久福利在线 | 欧美一级片免费观看 | 日韩在线观看不卡 | 欧美一级免费在线 | 在线韩国电影免费观影完整版 | 中国一区二区视频 | 久久网站免费 | 一级a毛片高清视频 | 欧美日韩国产精品一区二区 | 国产自在线| 久草视频首页 | 高清视频一区二区三区 | 日韩美女免费线视频 | 久久久久免费电影 | 久久国产精品偷 | 在线观看韩国av | 黄色小说在线观看视频 | 国产97在线观看 | 在线日韩中文字幕 | 日韩精品一区二区三区不卡 | 国产精品国产自产拍高清av | 91天堂素人约啪 | 综合网天天 | 毛片1000部免费看 | 欧美做受69 | 国语黄色片 | 国产一级高清视频 | 亚洲乱码精品久久久久 | 欧美日韩网址 | 在线网站黄 | 干亚洲少妇 | 欧美 日韩 性 | 日韩欧美视频一区二区三区 | 日韩色中色 | 亚洲一区 av | 水蜜桃亚洲一二三四在线 | 国产中文字幕在线 | 18久久久久 | 国产午夜精品一区二区三区欧美 | 日本精品视频一区二区 | 日韩一区二区三区在线观看 | 亚洲乱码精品久久久久 | 91在线91拍拍在线91 | 久久亚洲人 | www.久久免费视频 | 国产精品一区二区三区免费视频 | 久久国产精品免费一区二区三区 | 亚洲天堂精品视频在线观看 | 三上悠亚一区二区在线观看 | 日韩免费b | 欧美在线观看视频一区二区三区 | 99在线精品视频 | 右手影院亚洲欧美 | 免费在线观看的av网站 | 免费观看的av网站 | 国产精品永久免费观看 | 国产123区在线观看 国产精品麻豆91 | 国产精品免费视频久久久 | 成+人+色综合 | 久久av免费观看 | 国产在线一区二区三区播放 | 国产亚洲成av人片在线观看桃 | 亚洲专区在线播放 | 国产精品原创在线 | 久久精品成人热国产成 | 亚洲国产wwwccc36天堂 | 欧美一二三视频 | 黄色av一级片 | 偷拍精品一区二区三区 | 伊人天天狠天天添日日拍 | 最近高清中文在线字幕在线观看 | 中文字幕在线视频网站 | 超碰成人免费电影 | 蜜臀久久99静品久久久久久 | 99热国产在线观看 | 射九九 | 九色91福利 | 伊人中文在线 | 成人91在线观看 | 黄色片亚洲| av黄色大片 | 丁香av| 久久久久久高潮国产精品视 | 亚洲电影网站 | 国产精品99久久99久久久二8 | 天堂av一区二区 | 亚洲高清色综合 | 久草在线| 天天干天天摸天天操 | 国产在线视频在线观看 | 狠狠干夜夜爱 | 99久久精品日本一区二区免费 | 91精品对白一区国产伦 | 色www永久免费 | 天天操伊人 | 国产一区二区精品久久 | 欧美日韩精品影院 | 99久在线精品99re8热视频 | 国产精品高潮呻吟久久久久 | 2019中文在线观看 | 国内精品视频在线播放 | 成人视屏免费看 | 国产一区二区不卡在线 | 91视频在线免费 | 色综合天天狠天天透天天伊人 | 激情欧美一区二区三区 | 精品福利网站 | 欧美久久久久久久久久 | 国产涩涩网站 | 日韩视频a | 四虎永久免费网站 | 久草在线免费色站 | 亚洲少妇xxxx| 国产精品成人在线 | 黄色一区二区在线观看 | 久久久影院官网 | av在线一 | 国产亚洲在线观看 | 六月丁香综合网 | 四虎免费av | 国产永久免费高清在线观看视频 | 国产精品久久片 | 久久精国产 | 夜夜夜草 | 日韩激情免费视频 | 五月婷婷激情五月 | 97超视频在线观看 | 精品久久免费看 | 国产精品专区h在线观看 | 成人午夜电影久久影院 | 国产精品一码二码三码在线 | 91视频链接| 一区二区不卡 | 精品久久久久久久久久久院品网 | 亚洲精品在线网站 | 亚洲日本在线视频观看 | 国产丝袜在线 | 超级碰碰碰免费视频 | 日韩| 日韩黄色在线观看 | 久久五月婷婷综合 | 欧美日韩免费一区 | 91成人精品一区在线播放69 | 国产精品va在线播放 | 免费看的黄色片 | 免费精品在线观看 | 日韩字幕 | 色综合久久久久网 | 日韩免费在线视频 | 五月天久久 | 一区电影 | 国产免费激情久久 | 免费美女久久99 | 亚洲综合在线五月 | 成人毛片一区二区三区 | 黄色性av| 久久久男人的天堂 | 不卡中文字幕在线 | 亚洲爽爽网 | 日日夜夜人人精品 | 亚洲码国产日韩欧美高潮在线播放 | 成人久久久精品国产乱码一区二区 | 香蕉97视频观看在线观看 | 日韩理论电影在线观看 | 在线成人一区二区 | 国产色在线视频 | 麻豆91精品视频 | 亚洲欧洲日韩在线观看 | 久久9999久久 | 在线观看免费高清视频大全追剧 | 蜜臀aⅴ精品一区二区三区 久久视屏网 | 丰满少妇在线观看网站 | 午夜精品福利一区二区 | 国产精品午夜久久久久久99热 | 深爱激情五月网 | 欧美少妇18p | 日本高清免费中文字幕 | 免费精品国产va自在自线 | 久久久久蜜桃 | 91网页版在线观看 | 欧美日韩中文国产一区发布 | 成人午夜免费剧场 | 国产白浆视频 | 日韩视频一区二区三区在线播放免费观看 | 精品电影一区 | 最近中文字幕在线中文高清版 | 色综合五月天 | 色先锋av资源中文字幕 | 国产亚洲欧美精品久久久久久 | 久久久久五月天 | 欧美视频在线观看免费网址 | 亚洲人xxx| 久久国产精品久久国产精品 | 男女激情片在线观看 | 久久免费公开视频 | 亚洲国产黄色片 | 99精品久久久久久久 | 国产一级电影免费观看 | 久久精品这里都是精品 | 96视频免费在线观看 | 精品伦理一区二区三区 | 91九色视频观看 | 日韩欧美高清在线观看 | 日韩精品一区二区三区中文字幕 | 久久久久欠精品国产毛片国产毛生 | 免费在线国产 | 欧美a视频在线观看 | 99久久精品免费看国产免费软件 | 992tv成人免费看片 | 激情丁香综合五月 | 免费污片| 国产录像在线观看 | 日韩精品视频一二三 | 久久精品99视频 | 日日射av| 久久精品黄色 | 久久怡红院 | 在线看免费| 国产精品久久嫩一区二区免费 | 国产视频 亚洲视频 | 日韩三级视频在线观看 | 国产成人高清在线 | 天天射天天舔天天干 | 久久久精品成人 | 久久免费av电影 | 91视频在线国产 | 亚洲草视频 | 婷婷五天天在线视频 | 亚洲精品久久久久久久蜜桃 | 亚洲欧洲成人 | 日韩深夜在线观看 | 黄色成人av网址 | 日韩特黄一级欧美毛片特黄 | 日韩一区二区三 | 日韩欧美一级二级 | 天天综合网久久 | 天躁狠狠躁| 日本精品在线 | 日韩av资源在线观看 | 色狠狠综合天天综合综合 | 亚洲aⅴ免费在线观看 | 亚洲精品www.| 国产精品欧美久久 | 久久久免费在线观看 | 日韩区欠美精品av视频 | 婷婷激情影院 | 亚洲精品动漫久久久久 | 91成版人在线观看入口 | 色婷婷激情电影 | 精品国产电影一区 | 97视频人人 | 色婷婷婷 | 亚洲精品中文在线 | 人人爽人人爱 | 成年人网站免费观看 | 91九色国产蝌蚪 | 天天干 天天摸 天天操 | 中文字幕在线观看完整版 | 久久久久久久久福利 | 成人黄色国产 | av高清影院 | 久久国产影视 | 欧美日韩免费在线视频 | 黄色小网站在线 | 久久国产亚洲视频 | 国产伦理久久精品久久久久_ | 欧美成年网站 | 91理论片午午伦夜理片久久 | 久久草草影视免费网 | 欧美日韩在线观看一区二区三区 | 国产欧美日韩一区 | 日日草av | 美女视频黄免费的久久 | 日韩av视屏 | 色全色在线资源网 | 亚洲天堂社区 | 日本韩国中文字幕 | 久久久久久久久久久黄色 | 国产一卡久久电影永久 | 国产精品久久久毛片 | 久久9999久久免费精品国产 | 粉嫩高清一区二区三区 | 欧美日韩久久一区 | 九九九免费视频 | 中文字幕日韩一区二区三区不卡 | 国产精品激情偷乱一区二区∴ | 国产精品女同一区二区三区久久夜 | 色播五月婷婷 | 狠狠干夜夜爽 | 色丁香久久 | 日本中文字幕免费观看 | 2019国产精品 | 国产最新视频在线观看 | 伊人热 | 免费a v视频 | 97色婷婷人人爽人人 | 久久99久国产精品黄毛片入口 | 99精品国产高清在线观看 | 美女视频黄是免费的 | 国产第一页精品 | 亚洲精品视频在线观看视频 | 欧美大片www | 久久久久久久网 | 国产一区二区三区午夜 | 久草在线免费资源站 | 热re99久久精品国产99热 | 爱爱av在线 | 91一区啪爱嗯打偷拍欧美 | 91亚洲视频在线观看 | 成人av一区二区兰花在线播放 | 国产69精品久久久久久久久久 | 91热视频在线观看 | 国产高清在线免费视频 | 亚洲精品视频二区 | 性色av一区二区三区在线观看 | www.天天成人国产电影 | 欧美精品三级在线观看 | 亚洲国产成人在线 | 69精品人人人人 | 综合激情 | 精品在线亚洲视频 | 亚洲精品永久免费视频 | 国产精品午夜免费福利视频 | 日日天天| 久久成人国产 | 国产精品久久久久婷婷二区次 | 日本中文字幕网站 | 欧美日在线观看 | 欧美性极品xxxx做受 | 免费在线精品视频 | 国产色a在线观看 | 日韩中文免费视频 | 操一草 | 久久久99精品免费观看 | 久久成人午夜 | 色婷久久 | 国产精品国产三级国产aⅴ无密码 | 九色精品免费永久在线 | 91一区二区三区在线观看 | 欧美午夜精品久久久久久孕妇 | 天天操天天射天天 | 天天综合中文 | 国产精品福利在线播放 | 婷婷色伊人 | 天天曰天天 | 又黄又色又爽 | 日女人电影 | 欧美激情视频在线观看免费 | a电影免费看 | 中文免费在线观看 | 日韩中文幕 | 免费成人在线观看视频 | 97av精品| 欧美日韩一区二区免费在线观看 | 久久久久黄色 | 日韩免费电影网 | 日韩字幕在线观看 | 久久a级片| 99久久久久久 | 免费影视大全推荐 | 日韩在线电影一区二区 | 国产一区精品在线观看 | 久久伊人国产精品 | 色综合久久中文字幕综合网 | wwwav视频| 亚洲三级毛片 | 久草在线在线精品观看 | 日日碰狠狠添天天爽超碰97久久 | 激情网色 | 精品毛片在线 | 亚洲黄色在线免费观看 | 日日噜噜噜噜夜夜爽亚洲精品 | 激情在线免费视频 | 免费亚洲精品视频 | 国产成人在线一区 | 国产午夜精品一区二区三区在线观看 | 色婷婷欧美 | 999视频在线观看 | 国产精品一区二区三区久久久 | 久久精品日产第一区二区三区乱码 | 欧美日韩免费看 | 激情五月开心 | 99久久久久免费精品国产 | 免费看十八岁美女 | 中文字幕日韩电影 | 69精品久久久 | 99久久精品无码一区二区毛片 | 中文字幕日韩av | 天天天天天天天天操 | 免费在线观看不卡av | 中文字幕精品一区久久久久 | 亚州av网站大全 | 久久久久久久影视 | 69欧美视频| 99欧美| 97超碰在线视 | 黄色软件网站在线观看 | 欧美成人精品欧美一级乱黄 | 亚洲精品福利在线观看 | 日韩av一区二区在线 | 狠狠狠色丁香综合久久天下网 | 九九热re| 在线午夜 | av线上免费看 | 久久天堂影院 | 激情五月播播久久久精品 | 免费看黄色毛片 | 日本资源中文字幕在线 | 午夜久久| 美女视频久久黄 | 成人久久影院 | 久久高清av | 成人午夜黄色 | 精品美女在线视频 | 日本最新一区二区三区 | 日韩精品视频免费专区在线播放 | 超碰在线观看99 | 国产精品久久久久久一区二区三区 | 97爱爱爱| 久久亚洲人| 日本不卡视频 | 日韩高清黄色 | 欧美一区二区在线刺激视频 | 黄色avwww | 亚洲精品久久久久久久不卡四虎 | 亚洲午夜电影网 | 久久久99精品免费观看乱色 | 国产成人精品一区一区一区 | 午夜精品久久久久久久久久久久 | 久久综合给合久久狠狠色 | aaa亚洲精品一二三区 | 亚州精品天堂中文字幕 | 69国产盗摄一区二区三区五区 | 色成人亚洲| 国产老太婆免费交性大片 | 欧美大jb | 99热在线精品观看 | 亚洲精品婷婷 | 亚洲国产精品传媒在线观看 | 在线视频免费观看 | 国产免费又粗又猛又爽 | 亚洲免费精彩视频 | 国产99久久久国产 | 丝袜制服综合网 | 四虎永久精品在线 | 午夜影院先 | 美女福利视频一区二区 | 一本一本久久a久久精品综合小说 | 国产123av| 91精品欧美一区二区三区 | 日韩在线精品 | 黄色网在线免费观看 | 激情综合色综合久久综合 | 国产精品毛片一区二区 | 欧美韩国日本在线 | 免费a级大片 | 超碰成人免费电影 | 日韩经典一区二区三区 | 精品久久久久久久久久久久久久久久 | 丁香六月婷婷综合 | 国产精品热视频 | 精品久久久久久亚洲综合网站 | 精品视频免费看 | 日韩视频www | 96久久久 | 91精品国产91久久久久福利 | 免费色视频网站 | 欧美a级一区二区 | 91免费高清视频 | 国产视频不卡 | 欧美一区二区三区在线看 | 亚洲一区二区天堂 | 国产成人久久精品一区二区三区 | 99久久精品费精品 | 97超碰人人爱 | 婷婷丁香国产 | 中文字幕av一区二区三区四区 | 91片网| 久久精品一区二区三区国产主播 | 欧美精品乱码久久久久久 | 91精品啪在线观看国产线免费 | 天天操天天操天天干 | 一区二区 久久 | 亚洲精品在线国产 | 五月婷婷欧美视频 | 欧美精品生活片 | 天天操天 | 国产综合婷婷 | 国产第一页在线播放 | 国产精品黄网站在线观看 | 在线亚洲精品 | 日本三级大片 | 69精品在线观看 | 国产九九精品视频 | 国内精品久久久久影院男同志 | 欧美人人爱 | 狠狠躁天天躁 | 激情av资源| 天天射日| 久久久精品国产一区二区电影四季 | 国产精品第十页 | 久久久国产精品视频 | 六月婷婷久香在线视频 | 天天操天天爽天天干 | 日韩一区二区在线免费观看 | 天天操天天爱天天干 | 日韩在线视频不卡 | 99久e精品热线免费 99国产精品久久久久久久久久 | 国产精品对白一区二区三区 | 亚洲丝袜中文 | 黄网站色 | 亚一亚二国产专区 | 久久9999久久免费精品国产 | 在线成人免费电影 | 免费看污网站 | 国产小视频在线看 | 国产片网站 | 久久国产精品99久久人人澡 | 欧美精品中文在线免费观看 | 亚洲国产精品99久久久久久久久 | 中文字幕在线观看网址 | 日韩视频三区 | 久久不卡日韩美女 | 久久99国产一区二区三区 | 久久精品视频在线 | 激情综合网天天干 | 99在线精品免费视频九九视 | 久久久国产毛片 | 国产偷国产偷亚洲清高 | 婷婷开心久久网 | 激情视频综合网 | 国产中文字幕网 | 亚洲国产一区二区精品专区 | 丁香视频全集免费观看 | 亚洲黄色成人网 | 黄色一级动作片 | 国产精品久久久免费 | 亚洲va欧洲va国产va不卡 | av丁香| 国产精品综合久久久久 | 国产又粗又猛又色 | 国产成人333kkk | 蜜桃麻豆www久久囤产精品 | 91在线播放视频 | 国产精品成人自拍 | 久久久国际精品 | 蜜臀av性久久久久蜜臀av | 国产精品久久久久久久免费大片 | 国产高清久久久 | 中文字幕一区二区在线播放 | 日韩av在线不卡 | 欧美不卡视频在线 | 国产999视频 | 性色av免费在线观看 | 四虎成人精品 | 久99视频| 国产一级免费在线 | 亚洲男女精品 | 国产精品久久久久久久av电影 | 国产中年夫妇高潮精品视频 | 久久成人国产精品入口 | 911久久| www.黄色网.com | 日韩一区二区三区免费电影 | 人人超碰97| 亚洲免费不卡 | 日韩视频一区二区 | 狠狠干电影 | 成人毛片一区二区三区 | 91精品国产99久久久久久红楼 | 欧美性生爱 | 色多视频在线观看 | 色婷婷视频网 | 久久精品高清视频 | 色中色亚洲 | 久99精品| 综合激情网... | 欧美日韩国产精品一区二区亚洲 | 久久草| 国产亚洲精品久久久久久无几年桃 | 久久艹人人 | 国产99久久精品一区二区永久免费 | 久草视频观看 | 久久久久久毛片精品免费不卡 | 一区二区欧美在线观看 | 亚洲欧美偷拍另类 | av一级在线观看 | 精品国产91亚洲一区二区三区www | 亚洲一级电影在线观看 | 免费观看的黄色片 | 91福利影院在线观看 | 久久久www成人免费精品张筱雨 | 免费福利视频网 | 欧美日韩电影在线播放 | 国产亚洲一区二区三区 | 国产精品一区二区三区四区在线观看 | 999久久a精品合区久久久 | 一级黄色片毛片 | 蜜臀91丨九色丨蝌蚪老版 | 天天操天天添天天吹 | 青青草视频精品 |